home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UMacAppUtilities.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  70.5 KB  |  2,649 lines  |  [TEXT/MPS ]

  1. // UMacAppUtilities.cp
  2. // Copyright © 1984-1991 Apple Computer, Inc.  All rights reserved.
  3.  
  4. #ifndef __UMACAPPUTILITIES__
  5. #include <UMacAppUtilities.h>
  6. #endif
  7.  
  8. #ifndef __STDIO__
  9. #include <StdIo.h>
  10. #endif
  11.  
  12. #ifndef __TRAPS__
  13. #include <Traps.h>
  14. #endif
  15.  
  16. #ifndef __SYSEQU__
  17. #include <SysEqu.h>
  18. #endif
  19.  
  20. #ifndef __DEVICES__
  21. #include <Devices.h>
  22. #endif
  23.  
  24. #ifndef __UGEOMETRY__
  25. #include <UGeometry.h>
  26. #endif
  27.  
  28. #ifndef __ULOMEM__
  29. #include <ULoMem.h>
  30. #endif
  31.  
  32. #ifndef __MEMORY__
  33. #include <Memory.h>
  34. #endif
  35.  
  36. #ifndef __TOOLUTILS__
  37. #include <ToolUtils.h>
  38. #endif
  39.  
  40. #ifndef __RESOURCES__
  41. #include <Resources.h>
  42. #endif
  43.  
  44. #ifndef __FONTS__
  45. #include <Fonts.h>
  46. #endif
  47.  
  48. #ifndef __SCRAP__
  49. #include <Scrap.h>
  50. #endif
  51.  
  52. #ifndef __ERRORS__
  53. #include <Errors.h>
  54. #endif
  55.  
  56. #ifndef __DIALOGS__
  57. #include <Dialogs.h>
  58. #endif
  59.  
  60. #ifndef __PACKAGES__
  61. #include <Packages.h>
  62. #endif
  63.  
  64. #ifndef __SCRIPT__
  65. #include <Script.h>
  66. #endif
  67.  
  68. #ifndef __OSEVENTS__
  69. #include <OSEvents.h>
  70. #endif
  71.  
  72. #ifndef __SANE__
  73. #include <SANE.h>
  74. #endif
  75.  
  76. #ifndef __GESTALTEQU__
  77. #include <GestaltEqu.h>
  78. #endif
  79.  
  80. #ifndef __QUICKDRAW__
  81. #include <QuickDraw.h>
  82. #endif
  83.  
  84. #ifndef __MENUS__
  85. #include <Menus.h>
  86. #endif
  87.  
  88. #ifndef    __UDEBUG__
  89. #include "UDebug.h"
  90. #endif
  91.  
  92. // extern definitions:
  93. extern WindowPtr gWorkPort;
  94. extern const unsigned char kFrame;
  95.  
  96. // constants
  97. const SignedByte initVal = 0xD3;            // debugging constant, odd at all byte boundaries 
  98.  
  99. // Global variables defined so that storage is allocated:
  100. #if qDebug
  101. Boolean gPreCondition = TRUE;
  102. Boolean gPostCondition = TRUE;
  103. Boolean gAssumeFocused = TRUE;                        /* make TView.AssumeFocused actually check
  104.                                                   focus */
  105. Boolean gDebugPrinting = FALSE;
  106. Boolean gExperimenting = FALSE;
  107. Boolean gIntenseDebugging = FALSE;
  108. Boolean gReportEvt = FALSE;
  109. Boolean gReportMenuChoices = FALSE;
  110. short gRsrcCheck = kRsrcCheckInterval;
  111. Boolean gShowCursorRegion = FALSE;
  112. Boolean gShowHelpRegion = FALSE;
  113. Boolean gShowInvalidations = FALSE;                    /* make TWindow.InvalidVRect graphically show
  114.                                                   the invalidation region */
  115. Boolean gShowSleepRegion = FALSE;
  116. Boolean gTraceIdle;
  117. #endif
  118.  
  119. const char* kCopyright = "MacApp® 3.0a2 Copyright © 1984-1991 Apple Computer, Inc.  All rights reserved.";
  120. short gApplicationRefNum;
  121. ConfigRecord gConfiguration;
  122. BoolStrType gBoolString[2];                // = { "\pFALSE", "\pTRUE" };
  123.  
  124. Boolean gToolBoxInitialized = FALSE;
  125. Boolean gUDialogInitialized = FALSE;
  126. Boolean gUGridViewInitialized = FALSE;
  127. Boolean gUPrintingInitialized = FALSE;
  128. Boolean gUTEViewInitialized = FALSE;
  129. Ptr gStrippedAddress = NULL;
  130.  
  131. ProcPtr gFieldToStrRtn = NULL;
  132. ProcPtr gFieldToCountRtn = NULL;
  133.  
  134. Boolean gDeadStripSuppression = FALSE;
  135. TEHandle gMATextBoxTE = NULL;
  136. WordBreakProcPtr gTEDefaultWordBreak = NULL;
  137. VHSelect gOrthogonal[2];
  138.  
  139. Rect gZeroRect(0, 0, 0, 0);
  140. Point gZeroPt(0, 0);
  141. VPoint gZeroVPt(0, 0);
  142. VRect gZeroVRect(0, 0, 0, 0);
  143.  
  144. RGBColor gRGBBlack;
  145. RGBColor gRGBWhite;
  146. RGBColor gRGBRed;
  147. RGBColor gRGBGreen;
  148. RGBColor gRGBBlue;
  149.  
  150. // These are utilities.    Treat them like language extensions. 
  151. #pragma $W+
  152. #pragma $R-
  153. #pragma $Init-
  154. #pragma $OV-
  155. #if qNames
  156. #pragma $D+
  157. #endif
  158.  
  159. //--------------------------------------------------------------------------------------------------
  160. #pragma segment MAUtilitiesRes
  161.  
  162. Boolean CWMgrIterator::More()
  163. {
  164.     return (fCurrentWindow != NULL);
  165. }
  166.  
  167. //--------------------------------------------------------------------------------------------------
  168. #pragma segment MAUtilitiesRes
  169.  
  170. void CWMgrIterator::Reset()
  171. {
  172.     fCurrentWindow = GetWindowList();
  173. }
  174.  
  175. //--------------------------------------------------------------------------------------------------
  176. #pragma segment MAUtilitiesRes
  177.  
  178. void CWMgrIterator::Advance()
  179. {
  180.     if (fCurrentWindow)
  181.     {
  182.         fCurrentWindow = (WindowPtr)(((WindowPeek)fCurrentWindow)->nextWindow);
  183.  
  184.         while (fCurrentWindow && (fCurrentWindow == gWorkPort))
  185.             // ignore the work window
  186.             fCurrentWindow = (WindowPtr)(((WindowPeek)fCurrentWindow)->nextWindow);
  187.     }
  188. }
  189.  
  190. //--------------------------------------------------------------------------------------------------
  191. #pragma segment MAUtilitiesRes
  192.  
  193. pascal Boolean CanWriteLn(void)
  194.  
  195. {
  196. #if qDebug
  197.     return DebugCanWriteLn();
  198. #else
  199.     return FALSE;
  200. #endif
  201.  
  202. }
  203.  
  204. //--------------------------------------------------------------------------------------------------
  205. #pragma segment MAUtilitiesRes
  206.  
  207. pascal Boolean CanReadLn(void)
  208.  
  209. {
  210. #if qDebug
  211.     return DebugCanReadLn();
  212. #else
  213.     return FALSE;
  214. #endif
  215.  
  216. }
  217.  
  218. //--------------------------------------------------------------------------------------------------
  219. #pragma segment MAUtilitiesRes
  220.  
  221. pascal Boolean CompareMultiByteChars(const Str31& first,
  222.                                      const Str31& second,
  223.                                      Boolean caseSens)
  224. {
  225.     short textOffset = 0;
  226.     Boolean done = FALSE;
  227.     Boolean areEqual;
  228.     Str31 theChars = first;                // point to first char in string (after length byte)
  229.     Ptr    theCharPtr = (Ptr) &theChars;
  230.     theCharPtr++;
  231.  
  232.     do
  233.     {
  234.         short byteType = CharByte(theCharPtr, textOffset);// textOffset is zero-based 
  235.  
  236.         ++textOffset;
  237.         areEqual = first[textOffset] == second[textOffset];
  238.         switch (byteType)
  239.         {
  240.                 // special case single byte characters to allow lower case characters to map to
  241.                 // upper case characters
  242.             case smSingleByte:
  243.                 if (caseSens)
  244.                     areEqual = (first[1] == second[1]);
  245.                 else
  246.                     areEqual = (LowerChar(first[1]) == LowerChar(second[1]));
  247.                 done = TRUE;
  248.                 break;
  249.  
  250.             case smFirstByte:
  251.                 done =!areEqual;                // we're done if they don't match 
  252.                 break;
  253.  
  254.             case smLastByte:
  255.                 done = TRUE;
  256.                 break;
  257.  
  258.             case smMiddleByte:
  259.                 done =!areEqual;                // we're done if they don't match 
  260.                 break;
  261.         }
  262.     } while (!done);
  263.     return areEqual;
  264. }
  265.  
  266. //--------------------------------------------------------------------------------------------------
  267. #pragma segment MAUtilitiesRes
  268.  
  269. pascal short CompareStrings(const Str255& first,
  270.                             const Str255& second)
  271.  
  272. {
  273.     return RelString(first, second, TRUE, TRUE);
  274. }
  275.  
  276. //--------------------------------------------------------------------------------------------------
  277. #pragma segment MAUtilitiesRes
  278.  
  279. pascal void CopyStr255(const Str255& fmStr,
  280.                        Ptr toAddr)
  281. {
  282.     Str255 copyString = fmStr;
  283.     
  284.     BlockMove((Ptr) ©String, toAddr, copyString.Length() + 1);
  285. }
  286.  
  287. //--------------------------------------------------------------------------------------------------
  288. #pragma segment MAUtilitiesRes
  289.  
  290. pascal void DefaultSize(short& theSize)
  291.  
  292. {
  293.     if (theSize == GetDefFontSize())
  294.         theSize = 0;
  295. }
  296.  
  297. //--------------------------------------------------------------------------------------------------
  298. #pragma segment MAUtilitiesRes
  299.  
  300. pascal Handle DisposeIfHandle(Handle aHandle)
  301.  
  302. {
  303.  
  304.     if (aHandle)
  305.     {
  306.         if (!qDebug)
  307.             DisposHandle(aHandle);
  308.         else
  309.         {
  310.             if (IsHandle(aHandle))                // Test handlehood 
  311.             {
  312.                 char handleBits = HGetState(aHandle);
  313.                 if (IsHandlePurged(aHandle))    // h might have been purged 
  314.                     DisposHandle(aHandle);
  315.                 else if (MemError() != noErr)
  316.                 {
  317.                     fprintf(stderr, "Handle was so bad I couldn't even get the handle bits!\nBad Handle: %p\n", aHandle);
  318.                     ProgramBreak("");
  319.                 }
  320.                 else if (IsAResource(aHandle))
  321.                 {
  322.                     fprintf(stderr, "Trying to dispose a resource handle\nBad Handle: %p\n", aHandle);
  323.                     ProgramBreak("");
  324.                 }
  325.                 else
  326.                 {
  327.                     // Set the handle contents to a real nice value for any dangling pointerciples 
  328.                     BlockSet((*aHandle), GetHandleSize(aHandle), initVal);
  329.                     DisposHandle(aHandle);
  330.                 }
  331.             }
  332.             else
  333.             {
  334.                 VerboseIsHandle(aHandle);        // Get the diagnosis printed 
  335.                 fprintf(stderr, "Trying to dispose an invalid handle\nBad Handle: %p\n", aHandle);
  336.                 ProgramBreak("");
  337.             }
  338.         }
  339.     }
  340.  
  341.     return NULL;
  342. }
  343.  
  344. //--------------------------------------------------------------------------------------------------
  345. #pragma segment MAUtilitiesRes
  346.  
  347. pascal PicHandle DisposeIfPicHandle(PicHandle aPicHandle)
  348.  
  349. {
  350.     if (aPicHandle)
  351.     {
  352.         if (!qDebug)
  353.             KillPicture(aPicHandle);
  354.         else
  355.         {
  356.             if (IsHandle((Handle)aPicHandle))    // Test handlehood 
  357.             {
  358.                 // Set the handle contents to a real nice value for any dangling pointerciples 
  359.                 BlockSet(*((Handle)aPicHandle), GetHandleSize((Handle)aPicHandle), initVal);
  360.                 KillPicture(aPicHandle);
  361.             }
  362.             else
  363.             {
  364.                 VerboseIsHandle((Handle)aPicHandle);// Get the diagnosis printed 
  365.                 fprintf(stderr, "Trying to dispose an invalid PicHandle)\nBad PicHandle: %p\n", aPicHandle);
  366.                 ProgramBreak("");
  367.             }
  368.         }
  369.     }
  370.  
  371.     return (PicHandle)NULL;
  372. }
  373.  
  374. //--------------------------------------------------------------------------------------------------
  375. #pragma segment MAUtilitiesRes
  376.  
  377. pascal Ptr DisposeIfPtr(Ptr aPtr)
  378.  
  379. {
  380.     if (aPtr)
  381.     {
  382.         if (!qDebug)
  383.             DisposPtr(aPtr);
  384.         else
  385.         {
  386.             // Test pointerhood, ??? Shouldn't we have a real test here? 
  387.             if (!((long)aPtr & 0x1))
  388.             {
  389.                 BlockSet(aPtr, GetPtrSize(aPtr), initVal);
  390.                 DisposPtr(aPtr);
  391.             }
  392.             else
  393.             {
  394.                 fprintf(stderr, "Trying to dispose an invalid pointer\nBad Pointer: %p\n", aPtr);
  395.                 ProgramBreak("");
  396.             }
  397.         }
  398.     }
  399.  
  400.     return NULL;
  401. }
  402.  
  403. //--------------------------------------------------------------------------------------------------
  404. #pragma segment MAUtilitiesRes
  405.  
  406. pascal RgnHandle DisposeIfRgnHandle(RgnHandle aRgnHandle)
  407.  
  408. {
  409.     if (aRgnHandle)
  410.     {
  411.         if (!qDebug)
  412.             DisposeRgn(aRgnHandle);
  413.         else
  414.         {
  415.             // Test handlehood 
  416.             if (IsHandle((Handle)aRgnHandle))
  417.             {
  418.                 // Set the handle contents to a real nice value for any dangling pointerciples 
  419.                 BlockSet(*((Handle)aRgnHandle), GetHandleSize((Handle)aRgnHandle), initVal);
  420.                 DisposeRgn(aRgnHandle);
  421.             }
  422.             else
  423.             {
  424.                 VerboseIsHandle((Handle)aRgnHandle);// Get the diagnosis printed 
  425.                 fprintf(stderr, "Trying to dispose an invalid RgnHandle.\nBad RgnHandle: %p\n", aRgnHandle);
  426.                 ProgramBreak("");
  427.             }
  428.         }
  429.     }
  430.  
  431.     return (RgnHandle)NULL;
  432. }
  433.  
  434. //--------------------------------------------------------------------------------------------------
  435. #pragma segment MAUtilitiesRes
  436.  
  437. pascal SectionHandle DisposeIfSectionHandle(SectionHandle aSectionHandle)
  438.  
  439. {
  440.     if (aSectionHandle)
  441.     {
  442.         if (!qDebug)
  443.         {
  444.             DisposeIfHandle((Handle)(*aSectionHandle)->alias);    // dispose of the alias
  445.             DisposeIfHandle((Handle)aSectionHandle);            // dispose of the SectionHandle
  446.         }
  447.         else
  448.         {
  449.             // Test handlehood 
  450.             if (IsHandle((Handle)aSectionHandle))
  451.             {
  452.                 DisposeIfHandle((Handle)(*aSectionHandle)->alias);    // dispose of the alias
  453.  
  454.                 // Set the handle contents to a real nice value for any dangling pointerciples 
  455.                 BlockSet(*((Handle)aSectionHandle), GetHandleSize((Handle)aSectionHandle), initVal);
  456.                 DisposeIfHandle((Handle)aSectionHandle);            // dispose of the SectionHandle
  457.             }
  458.             else
  459.             {
  460.                 VerboseIsHandle((Handle)aSectionHandle);    // Get the diagnosis printed 
  461.                 fprintf(stderr, "Trying to dispose an invalid SectionHandle.\nBad SectionHandle: %p\n", aSectionHandle);
  462.                 ProgramBreak("");
  463.             }
  464.         }
  465.     }
  466.  
  467.     return (SectionHandle)NULL;
  468. }
  469.  
  470. //--------------------------------------------------------------------------------------------------
  471. #pragma segment MAUtilitiesRes
  472.  
  473. pascal void EachWMgrWindowDo(pascal void(* DoToWMgrWindow)(WindowPtr theWMgrWindow,
  474.                                                            void* staticLink),
  475.                              void* staticLink)
  476. {
  477.     CWMgrIterator iter;
  478.     
  479.     for (WindowPtr aWindowPtr = iter.FirstWMgrWindow(); iter.More(); aWindowPtr = iter.NextWMgrWindow())
  480.         DoToWMgrWindow(aWindowPtr, staticLink);
  481. }
  482.  
  483. //--------------------------------------------------------------------------------------------------
  484. #pragma segment MAUtilitiesRes
  485.  
  486. // returns the window just before a given window.  Returns NULL if the given window is frontmost
  487. // or not found.
  488. pascal WindowPtr FindWindowBefore(WindowPtr theWindow)
  489. {
  490.     CWMgrIterator iter;
  491.  
  492.     for (WindowPtr theWMgrWindow = iter.FirstWMgrWindow(); iter.More(); theWMgrWindow = iter.NextWMgrWindow())
  493.         if (((WindowPtr)((WindowPeek)theWMgrWindow)->nextWindow) == theWindow)
  494.             return theWMgrWindow;
  495.  
  496.     return NULL;
  497. }
  498.  
  499. //--------------------------------------------------------------------------------------------------
  500. #pragma segment MAUtilitiesRes
  501.  
  502. pascal short GetActualJustification(short justification)
  503.  
  504. {
  505.     if (justification == teFlushDefault)
  506.         return GetSysJust();
  507.     else
  508.         return justification;
  509. }
  510.  
  511. //--------------------------------------------------------------------------------------------------
  512. #pragma segment MAUtilitiesRes
  513.  
  514. pascal void GetDeskTopRegion(RgnHandle deskTopRgn)
  515.  
  516. {
  517.     if (qNeedsColorQD || gConfiguration.hasColorQD)// deskTopRgn = main screen rect 
  518.         RectRgn(deskTopRgn, (*GetMainDevice())->gdRect);
  519.     else
  520.         RectRgn(deskTopRgn, qd.screenBits.bounds);
  521.     UnionRgn(GetGrayRgn(), deskTopRgn, deskTopRgn);// deskTopRgn = grayRgn + deskTopRgn 
  522. }
  523.  
  524. //--------------------------------------------------------------------------------------------------
  525. #pragma segment MAUtilitiesRes
  526.  
  527. pascal short GetFontNum(const Str255& fontName)
  528.  
  529. {
  530.     short fontNum;
  531.     Str255 localFontName(fontName);
  532.  
  533.     UprString(localFontName, FALSE);
  534.     if (localFontName == kSysFontName)
  535.         fontNum = GetSysFont();
  536.     else if (localFontName == kApplFontName)
  537.         fontNum = GetAppFont();
  538.     else
  539.         GetFNum(fontName, fontNum);
  540.  
  541.     return fontNum;
  542. }
  543.  
  544. //--------------------------------------------------------------------------------------------------
  545. #pragma segment MAUtilitiesRes
  546.  
  547. pascal void GetIfBkColor(RGBColor& aColor)
  548.  
  549. {
  550.     const short BlackBit = 5;
  551.     const short YellowBit = 6;
  552.     const short MagentaBit = 7;
  553.     const short CyanBit = 8;
  554.  
  555.     if (qNeedsColorQD || gConfiguration.hasColorQD)
  556.         GetBackColor(aColor);
  557.     else
  558.     {                                            // Map old, dumb CMYB system to RGB color 
  559.         /*                        xxxxxxx C.MY B rgb w b    == RGB
  560.           blackColor        ==  33 == 0000000 0.00 1 000 0 1    == 000
  561.           whiteColor        ==  30 == 0000000 0.00 0 111 1 0    == 111
  562.           redColor        == 205 == 0000000 0.11 0 011 0 1    == 100
  563.           greenColor        == 341 == 0000000 1.01 0 101 0 1    == 010
  564.           blueColor        == 409 == 0000000 1.10 0 110 0 1    == 001
  565.           cyanColor        == 273 == 0000000 1.00 0 100 0 1    == 011
  566.           magentaColor    == 137 == 0000000 0.10 0 010 0 1    == 101
  567.           yellowColor     ==  69 == 0000000 0.01 0 001 0 1    == 110
  568.         */
  569.  
  570.         long oldColor = qd.thePort->bkColor;    // Fetch old color 
  571.         aColor = gRGBBlack;                        // Prime returned color to black 
  572.         if (oldColor & (0x1 << BlackBit))        // If color isn't black, force CMY == 111
  573.             oldColor = (oldColor | 0x1C0);
  574.         if (!(oldColor & (0x1 << CyanBit)))        // Absence of cyan == presence of red 
  575.             aColor.red = 0xFFFF;
  576.         if (!(oldColor & (0x1 << MagentaBit)))    // Absence of magenta == presence of green 
  577.             aColor.green = 0xFFFF;
  578.         if (!(oldColor & (0x1 << YellowBit)))    // Absence of yellow == presence of blue 
  579.             aColor.blue = 0xFFFF;
  580.     }
  581. }
  582.  
  583. //--------------------------------------------------------------------------------------------------
  584. #pragma segment MAUtilitiesRes
  585.  
  586. pascal void GetIfColor(RGBColor& aColor)
  587.  
  588. {
  589.     const short BlackBit = 5;
  590.     const short YellowBit = 6;
  591.     const short MagentaBit = 7;
  592.     const short CyanBit = 8;
  593.  
  594.     if (qNeedsColorQD || gConfiguration.hasColorQD)
  595.         GetForeColor(aColor);
  596.     else
  597.     {                                            // Map old, dumb CMYB system to RGB color 
  598.         /*   xxxxxxx C.MY B rgb w b == RGB
  599.           blackColor  ==  33 == 0000000 0.00 1 000 0 1 == 000
  600.           whiteColor  ==  30 == 0000000 0.00 0 111 1 0 == 111
  601.           redColor == 205 == 0000000 0.11 0 011 0 1 == 100
  602.           greenColor  == 341 == 0000000 1.01 0 101 0 1 == 010
  603.           blueColor  == 409 == 0000000 1.10 0 110 0 1 == 001
  604.           cyanColor  == 273 == 0000000 1.00 0 100 0 1 == 011
  605.           magentaColor == 137 == 0000000 0.10 0 010 0 1 == 101
  606.           yellowColor  ==  69 == 0000000 0.01 0 001 0 1 == 110
  607.         */
  608.         long oldColor = qd.thePort->fgColor;    // Fetch old color 
  609.         aColor = gRGBBlack;                        // Prime returned color to black 
  610.         if (oldColor & (0x1 << BlackBit))        /* If color isn't black, force CMY == 111 */
  611.             oldColor = (oldColor | 0x1C0);
  612.         if (!(oldColor & (0x1 << CyanBit)))        // Absence of cyan == presence of red 
  613.             aColor.red = 0xFFFF;
  614.         if (!(oldColor & (0x1 << MagentaBit)))    // Absence of magenta == presence of green 
  615.             aColor.green = 0xFFFF;
  616.         if (!(oldColor & (0x1 << YellowBit)))    // Absence of yellow == presence of blue 
  617.             aColor.blue = 0xFFFF;
  618.     }
  619. }
  620.  
  621. //--------------------------------------------------------------------------------------------------
  622. #pragma segment MAUtilitiesRes
  623.  
  624. pascal short MAGetFontInfo(FontInfo& theFontInfo)
  625. // MAGetFontInfo may be used in place of GetFontInfo since it also returns the font height. 
  626.  
  627. {
  628.     GetFontInfo(theFontInfo);                    // get the current port's font info 
  629.     return (theFontInfo.ascent + theFontInfo.descent + theFontInfo.leading);// returns the font height 
  630. }
  631.  
  632. //--------------------------------------------------------------------------------------------------
  633. #pragma segment MAUtilitiesRes
  634.  
  635. pascal void GetPortFontInfo(short fontNum,
  636.                             Str255& fontName,
  637.                             short& fontSize)
  638.  
  639. {
  640.     if ((fontNum == systemFont) || (fontNum == GetSysFont()))
  641.     {
  642.         fontName = kSysFontName;
  643.         DefaultSize(fontSize);
  644.     }
  645.     else if ((fontNum == applFont) || (fontNum == GetAppFont()))
  646.     {
  647.         fontName = kApplFontName;
  648.         DefaultSize(fontSize);
  649.     }
  650.     else
  651.         GetFontName(fontNum, fontName);
  652. }
  653.  
  654. //--------------------------------------------------------------------------------------------------
  655. #pragma segment Main
  656.  
  657. pascal SignedByte LockHandleHigh(Handle h)
  658.  
  659. {
  660.     SignedByte savedState = SignedByte(0);
  661.     if (h)
  662.     {
  663.         if (qDebug &&!IsHandle(h))
  664.         {
  665.             VerboseIsHandle(h);                    // Get the diagnosis printed 
  666.             ProgramBreak("In LockHandleHigh: not handed a handle.");
  667.         }
  668.         else
  669.         {
  670.             savedState = HGetState(h);
  671.             HLockHi(h);                            // ??? check MemErr ??? 
  672.         }
  673.     }
  674.     return savedState;
  675. }
  676.  
  677. //--------------------------------------------------------------------------------------------------
  678. // These should be inline functions but CFront outlined them. No way to stop it
  679. // because of the way MacApp uses them. (e.g. Max(Max(x, y) z); causes outlining )
  680.  
  681. #pragma segment MAUtilitiesRes
  682.  
  683. long Max(long a, long b)
  684. {
  685.     return a > b ? a : b;
  686. }
  687.  
  688. long Min(long a, long b)
  689. {
  690.     return a < b ? a : b;
  691. }
  692.  
  693. //--------------------------------------------------------------------------------------------------
  694. #pragma segment MAUtilitiesRes
  695.  
  696. pascal Boolean IsFreeHandle(Handle aHandle)
  697. // Walk the free-list looking for the given handle 
  698.  
  699. {
  700.     THz applZone = ApplicZone();
  701.     Handle currHandle = (Handle)applZone->hFstFree;
  702.  
  703.     while (currHandle != NULL)
  704.     {
  705.         if (currHandle == aHandle)
  706.             return TRUE;
  707.         currHandle = (Handle) * currHandle;
  708.     }
  709.     return FALSE;
  710. }
  711.  
  712. //--------------------------------------------------------------------------------------------------
  713. #pragma segment MAUtilitiesRes
  714.  
  715. pascal Boolean IsColorPort(GrafPtr port)
  716. /* Returns TRUE if the GrafPort is a Color QD GrafPort
  717.   test is: IsColorPort = CGrafPtr(port)->portversion == 0xC000 */
  718.  
  719. {
  720.     if (port != NULL)
  721.         return ((((CGrafPtr)port)->portVersion) & 0xC000) == 0x0000C000;
  722.     else
  723.         return FALSE;
  724. }
  725.  
  726. //--------------------------------------------------------------------------------------------------
  727. #pragma segment MAUtilitiesRes
  728.  
  729. pascal Boolean IsAResource(Handle h)
  730.  
  731. {
  732.     const short kResourceNotFound = -1;
  733.     return HomeResFile(h) != kResourceNotFound;
  734. }
  735.  
  736. //--------------------------------------------------------------------------------------------------
  737. #pragma segment MAUtilitiesRes
  738.  
  739. pascal Boolean IsHandle(Handle h)
  740. // Returns true if handle appears valid. 
  741.  
  742. {
  743.     if (h == NULL)                                // Test handle NULLness 
  744.         return FALSE;                            // handle is NULL
  745.     else if (((long)h & 1) == 1)                // Test handle Oddness 
  746.         return FALSE;                            // handle is odd (How odd!)
  747.     else
  748.         return (((long) * h & 1) == 0);            // Test and return master pointer Oddness
  749. }
  750.  
  751. //--------------------------------------------------------------------------------------------------
  752. #pragma segment MAUtilitiesRes
  753.  
  754. pascal Boolean IsHandleLocked(Handle h)
  755. // Returns lockState of h. 
  756.  
  757. {
  758.     const short lockBit = 7;
  759.  
  760.     SignedByte handleBits = HGetState(h);
  761.     if (MemError() == noErr)                    // h might have been purged 
  762.         return (handleBits & (0x1 << lockBit));
  763.     else
  764.         return FALSE;
  765. }
  766.  
  767. //--------------------------------------------------------------------------------------------------
  768. #if qDebug
  769. #pragma segment MAUtilitiesRes
  770.  
  771. pascal Boolean IsHandlePurged(Handle h)
  772. // Returns purgeState of h. 
  773.  
  774. {
  775.     if (qDebug &&!IsHandle(h))
  776.     {
  777.         VerboseIsHandle(h);                        // Get the diagnosis printed 
  778.         ProgramBreak("IsHandlePurged was not handed a handle, pretty handy, eh?");
  779.         return TRUE;                            /* !!! What is a decent result. shouldn't
  780.                                                   developer just signal failure from the
  781.                                                   debugger. We need to force the issue */
  782.     }
  783.     else
  784.         return (*h == NULL);
  785. }
  786. #endif
  787.  
  788. //--------------------------------------------------------------------------------------------------
  789. #pragma segment MAUtilitiesRes
  790.  
  791. static Boolean IsThisKeyDown(const short theKey)
  792. {
  793.     union
  794.     {
  795.         KeyMap asMap;
  796.         Byte asBytes[16];
  797.     };
  798.  
  799.  
  800.     GetKeys(asMap);
  801.     return asBytes[theKey >> 3] & (1 << (theKey & 0x07)) ? true : false;
  802. }
  803.  
  804. //--------------------------------------------------------------------------------------------------
  805. #pragma segment MAUtilitiesRes
  806.  
  807. pascal Boolean IsCommandKeyDown(void)
  808.  
  809. {
  810.     const short kCommandKey = 55;
  811.     return IsThisKeyDown(kCommandKey);
  812. }
  813.  
  814. //--------------------------------------------------------------------------------------------------
  815. #pragma segment MAUtilitiesRes
  816.  
  817. pascal Boolean IsControlKeyDown(void)
  818.  
  819. {
  820.     const short kCtlKey = 0x3B;
  821.     return IsThisKeyDown(kCtlKey);
  822. }
  823.  
  824. //--------------------------------------------------------------------------------------------------
  825. #pragma segment MAUtilitiesRes
  826.  
  827. pascal Boolean IsOptionKeyDown(void)
  828.  
  829. {
  830.     const short kOptionKey = 58;
  831.     return IsThisKeyDown(kOptionKey);
  832. }
  833.  
  834. //--------------------------------------------------------------------------------------------------
  835. #pragma segment MAUtilitiesRes
  836.  
  837. pascal Boolean IsShiftKeyDown(void)
  838.  
  839. {
  840.     const short kShiftKey = 56;
  841.     return IsThisKeyDown(kShiftKey);
  842. }
  843.  
  844. //--------------------------------------------------------------------------------------------------
  845. #pragma segment MAUtilitiesRes
  846.  
  847. pascal short GetWindowVariant(WindowPtr theWindow)
  848.  
  849. {
  850.     // For MacApp 3.0 app's, _GetWVariant is *always* available.
  851.     return GetWVariant(theWindow);
  852.  
  853.     /*
  854.       if (TrapExists(_GetWVariant))
  855.       return GetWVariant(theWindow);
  856.       else
  857.       return BAND(0x0F, (((long) ((WindowPeek) theWindow)->windowDefProc) >> 24);
  858.     */
  859. }
  860.  
  861. //--------------------------------------------------------------------------------------------------
  862. #pragma segment MAUtilitiesRes
  863.  
  864. pascal short LengthRect(const Rect& r,
  865.                         VHSelect vhs)
  866.  
  867. {
  868.     return r.Length(vhs);
  869. }
  870.  
  871. //--------------------------------------------------------------------------------------------------
  872. #pragma segment MAUtilitiesRes
  873.  
  874. pascal VHSelect LongerSide(Rect& r)
  875.  
  876. {
  877.     if ((r.Length(vSel)) >= (r.Length(hSel)))
  878.         return vSel;
  879.     else
  880.         return hSel;
  881. }
  882.  
  883. //--------------------------------------------------------------------------------------------------
  884. #pragma segment MAUtilitiesRes
  885.  
  886. pascal VHSelect LongerVSide(VRect& r)
  887.  
  888. {
  889.     if ((r.Length(vSel)) >= (r.Length(hSel)))
  890.         return vSel;
  891.     else
  892.         return hSel;
  893. }
  894.  
  895. //--------------------------------------------------------------------------------------------------
  896. #pragma segment MADebug
  897.  
  898. pascal void LIntToHex(long decNumber,
  899.                       Str31& hexNumber,
  900.                       short noOfDigits)
  901.  
  902. {
  903.     short localNoOfDigits = (short)Min(noOfDigits, 8);
  904.     long localDecNumber = decNumber;
  905.     hexNumber[0] = (char)localNoOfDigits;
  906.     for (short i = localNoOfDigits; i >= 1; i--, localDecNumber = localDecNumber >> 4)
  907.         hexNumber[i] = kHexDigits[(localDecNumber & 15)];
  908. }
  909.  
  910. //--------------------------------------------------------------------------------------------------
  911. #pragma segment MAUtilitiesRes
  912.  
  913. pascal short LowerChar(short ch)
  914.  
  915. {
  916.     if ((ch >= 'A') && (ch <= 'Z'))
  917.         return ch + 32;
  918.     else
  919.         return ch;
  920. }
  921.  
  922. //--------------------------------------------------------------------------------------------------
  923. #pragma segment MAUtilitiesRes
  924.  
  925. pascal void LowerStr255(Str255& s)
  926.  
  927. {
  928.     for (short i = 1; i <= s.Length(); i++)
  929.         if ((s[i] >= 'A') && (s[i] <= 'Z'))
  930.             s[i] += 32;
  931. }
  932.  
  933. //--------------------------------------------------------------------------------------------------
  934. #pragma segment MAUtilitiesRes
  935.  
  936. pascal short MAUseResFile(short refNum)
  937. // UseResFile the newResFile and return the old CurResFile. 
  938.  
  939. {
  940.     short saveRefNum = CurResFile();
  941.     UseResFile(refNum);
  942.     return saveRefNum;
  943. }
  944.  
  945. //--------------------------------------------------------------------------------------------------
  946. #pragma segment MAUtilitiesRes
  947.  
  948. pascal long MinMax(long MinVal,
  949.                    long expression,
  950.                    long MaxVal)
  951. //Returns the bounded minimum and maximum 
  952.  
  953. {
  954.     return Min(Max(expression, MinVal), MaxVal);
  955. }
  956.  
  957. //--------------------------------------------------------------------------------------------------
  958. #pragma segment MADebug
  959.  
  960. pascal void NumberToHex(long theNumber,
  961.                         Str255& hexString,
  962.                         short hexDigits)
  963.  
  964. {
  965.     Str31 tempString;
  966.  
  967.     LIntToHex(theNumber, tempString, hexDigits);
  968.     hexString = "$" + tempString;
  969. }
  970.  
  971. //--------------------------------------------------------------------------------------------------
  972. #pragma segment MADebug
  973.  
  974. pascal void PointerToHex(long theNumber,
  975.                          Str255& hexString,
  976.                          short hexDigits)
  977.  
  978. {
  979.     Str31 tempString;
  980.  
  981.     if (theNumber == 0)
  982.         hexString = "NULL";
  983.     else
  984.     {
  985.         LIntToHex(theNumber, tempString, hexDigits);
  986.         hexString = "$" + tempString;
  987.     }
  988. }
  989.  
  990. //--------------------------------------------------------------------------------------------------
  991. #pragma segment MAFile
  992.  
  993. pascal long NumBlocks(long numBytes,
  994.                       long blkSize)
  995.  
  996. {
  997.     return (numBytes + blkSize - 1) / blkSize;
  998. }
  999.  
  1000. //--------------------------------------------------------------------------------------------------
  1001. #pragma segment MAUtilitiesRes
  1002.  
  1003. Handle pSaveHText;
  1004. Handle pMATextBoxHText = NULL;
  1005.  
  1006. pascal void StdNoRect(GrafVerb verb,
  1007.                       const Rect* r)
  1008. // StdNoRect filters out the rect drawing calls. 
  1009.  
  1010. {
  1011. }
  1012.  
  1013.  
  1014. void InitMyPrivateTE(const Rect& box,
  1015.                             short heapSize)
  1016.  
  1017. {
  1018.     const short kZoneHeader = 52;                // 52 bytes for header 
  1019.     const short kZoneTrailer = 12;                // 12 bytes for trailer 
  1020.     const short kMPBlockHeader = 8;                // 8 bytes for Master Pointer block hdr 
  1021.     const short kInitialMstrPtrs = 2;            // 2 master pointers created initially 
  1022.     const short kSlop = 20;                        // bytes of slop (just in case) 
  1023.     const short kZoneOverhead = kZoneHeader + kZoneTrailer + kMPBlockHeader + 4 * kInitialMstrPtrs + kSlop;// how large the zone overhead is 
  1024.     Ptr aTEZonePtr;
  1025.  
  1026.     gMATextBoxTE = TENew(box, box);
  1027.     if (gMATextBoxTE == NULL)                    // can't allocate space for our terecord 
  1028.         return;
  1029.  
  1030.     // • save off several items of interest
  1031.     gTEDefaultWordBreak = (*gMATextBoxTE)->wordBreak;
  1032.     pSaveHText = (*gMATextBoxTE)->hText;        // save the text handle 
  1033.  
  1034.     /* • Since TESetText (called near the end of MATextBox) hits the heap, we can speed this hit
  1035.       to the heap for small text lengths (<= 255), by allocating a special text handle in its own
  1036.       separate heap. We'll use this text handle whenever the text length is <= 255. */
  1037.  
  1038.     /* • create a separate heap */
  1039.     aTEZonePtr = NewPtr(heapSize + kZoneOverhead);
  1040.     if (aTEZonePtr == NULL)                        // can't allocate space for our heap 
  1041.         return;
  1042.     InitZone(NULL, kInitialMstrPtrs, aTEZonePtr + GetPtrSize(aTEZonePtr), aTEZonePtr);
  1043.  
  1044.     /* • InitZone sets the current zone to the newly created zone */
  1045.  
  1046.     /* • allocate our new text handle in our new heap zone */
  1047.     pMATextBoxHText = NewHandle(heapSize);        // the text handle 
  1048.  
  1049.     /* • restore the heap zone  */
  1050.     SetZone(ApplicZone());
  1051. }
  1052.  
  1053.  
  1054. pascal void MATextBox(Ptr text,
  1055.                       long itsLength,
  1056.                       const Rect& box,
  1057.                       short itsJust,
  1058.                       Boolean autoWrap,
  1059.                       ProcPtr wordBreak,
  1060.                       Boolean eraseFirst,
  1061.                       Boolean spaceForCaret)
  1062.  
  1063. {
  1064.  
  1065.     const short kTextBoxCaretSlopSize = 1;        /* Since TextBox uses TE to image the text,
  1066.                                                   we may need to adjust by 1 pixel. Reason:
  1067.                                                   TE draws beginning 1 pixel to the right to
  1068.                                                   allow for the insertion point (which we
  1069.                                                   won't have since this is drawn text, not
  1070.                                                   editable text).*/
  1071.     const short kMaxTEChars = 32000;            /* Actually TE suffers some other limitations
  1072.                                                   as well. Such as misbehaviour and or
  1073.                                                   bombing when the sum of the lineheights >
  1074.                                                   32k or a linewidth > 32k (overflows
  1075.                                                   QuickDraw space) But these are _MUCH_ more
  1076.                                                   difficult to test for in a quick way */
  1077.     const short kOurHeapSize = 255;                // our zone size 
  1078.  
  1079.     FontInfo fInfo;
  1080.     /* these next two locals eat up lots of stack space...this could be improved by allocating
  1081.       a pointer for the one that is used (eg allocate a pointer for myCQDProcs if CDQ available) */
  1082.     QDProcs myQDProcs;
  1083.     CQDProcs myCQDProcs;
  1084.     QDProcsPtr saveQDProcsPtr;
  1085.     Ptr saveRectProc;
  1086.     // Create my goodies if necessary 
  1087.     if (gMATextBoxTE == NULL)
  1088.     {
  1089.         InitMyPrivateTE(box, kOurHeapSize);
  1090.  
  1091.         if (gMATextBoxTE == NULL)                // couldn't allocate the TE handle 
  1092.         {
  1093.             TextBox(text, itsLength, box, itsJust);// default to TextBox in low memory 
  1094.             return;
  1095.         }
  1096.     }
  1097.  
  1098.     // Setup the work TE with the necessary parameters 
  1099.     GetFontInfo(fInfo);                            // Need to get font's height and ascent. 
  1100.  
  1101.     (SectRect((*(qd.thePort->clipRgn))->rgnBBox, box, (*gMATextBoxTE)->viewRect));
  1102.     (*gMATextBoxTE)->destRect = box;
  1103.     if (!spaceForCaret)                            /* widen the destrect but not the visrect.
  1104.                                                   This lets the 1 pixel wide area to the
  1105.                                                   left of all text and the right of all text
  1106.                                                   go unshown. */
  1107.     {
  1108.         (*gMATextBoxTE)->destRect.left = (*gMATextBoxTE)->destRect.left - kTextBoxCaretSlopSize;
  1109.         (*gMATextBoxTE)->destRect.right = (*gMATextBoxTE)->destRect.right + kTextBoxCaretSlopSize;
  1110.     }
  1111.  
  1112.     (*gMATextBoxTE)->inPort = qd.thePort;        // Current port and its characteristics 
  1113.  
  1114.     (*gMATextBoxTE)->txSize = qd.thePort->txSize;
  1115.     (*gMATextBoxTE)->txFont = qd.thePort->txFont;
  1116.     (*gMATextBoxTE)->txFace = qd.thePort->txFace;
  1117.     (*gMATextBoxTE)->fontAscent = fInfo.ascent;
  1118.     (*gMATextBoxTE)->lineHeight = fInfo.ascent + fInfo.descent + fInfo.leading;
  1119.     (*gMATextBoxTE)->just = itsJust;
  1120.  
  1121.     if (autoWrap)
  1122.         (*gMATextBoxTE)->crOnly = 0;            //if >=0, word wrap
  1123.     else
  1124.         (*gMATextBoxTE)->crOnly = -1;            //if <0, new line at Return only
  1125.  
  1126.     (*gMATextBoxTE)->wordBreak = gTEDefaultWordBreak;
  1127.  
  1128.     if (wordBreak != NULL)
  1129.         SetWordBreak((WordBreakProcPtr)wordBreak, gMATextBoxTE);// set the word break routine 
  1130.  
  1131.     if (pMATextBoxHText != NULL)                // if our private heap is set up 
  1132.     {
  1133.         if (itsLength > kOurHeapSize)
  1134.             (*gMATextBoxTE)->hText = pSaveHText;
  1135.         else
  1136.             (*gMATextBoxTE)->hText = pMATextBoxHText;
  1137.     }
  1138.  
  1139.     TESetText(text, Min(itsLength, kMaxTEChars), gMATextBoxTE);
  1140.  
  1141.     // if called with eraseFirst TRUE, then let TEUpdate image with its built-in EraseRect 
  1142.     if (eraseFirst)
  1143.         TEUpdate(box, gMATextBoxTE);
  1144.     else
  1145.     {
  1146.         /* replace the existing QD procs ( standard or externally supplied )
  1147.           so that the EraseRect in TEUpdate is ignored */
  1148.         saveQDProcsPtr = qd.thePort->grafProcs;
  1149.  
  1150.         if (saveQDProcsPtr == NULL)
  1151.         {
  1152.             if (IsColorPort(qd.thePort))
  1153.             {
  1154.                 SetStdCProcs(myCQDProcs);
  1155.                 myCQDProcs.rectProc = (Ptr) & StdNoRect;
  1156.                 qd.thePort->grafProcs = (QDProcsPtr) & myCQDProcs;
  1157.             }
  1158.             else
  1159.             {
  1160.                 SetStdProcs(myQDProcs);
  1161.                 myQDProcs.rectProc = (Ptr) & StdNoRect;
  1162.                 qd.thePort->grafProcs = &myQDProcs;
  1163.             }
  1164.         }
  1165.         else
  1166.         {
  1167.             saveRectProc = qd.thePort->grafProcs->rectProc;
  1168.             qd.thePort->grafProcs->rectProc = (Ptr) & StdNoRect;
  1169.         }
  1170.  
  1171.         // Now do the imaging 
  1172.         TEUpdate(box, gMATextBoxTE);
  1173.  
  1174.         // Restore the QDProcs 
  1175.         if (saveQDProcsPtr == NULL)
  1176.             qd.thePort->grafProcs = NULL;
  1177.         else
  1178.             qd.thePort->grafProcs->rectProc = saveRectProc;
  1179.  
  1180.     }
  1181. }
  1182.  
  1183. //--------------------------------------------------------------------------------------------------
  1184. #pragma segment MAUtilitiesRes
  1185.  
  1186. pascal void MADrawString(const Str255& s,
  1187.                          const Rect& box,
  1188.                          short justification)
  1189.  
  1190. {
  1191.     FontInfo theFontInfo;
  1192.     short widthOfString;
  1193.     short boxWidth;
  1194.     Rect localBox = box;
  1195.  
  1196.     GetFontInfo(theFontInfo);
  1197.     widthOfString = StringWidth(s);
  1198.     boxWidth = localBox.Length(hSel);
  1199.     if (widthOfString < boxWidth)
  1200.     {
  1201.         switch (GetActualJustification(justification))
  1202.         {
  1203.             case teFlushDefault:
  1204.                 break;
  1205.  
  1206.             case teCenter:
  1207.                 localBox.left += (boxWidth - widthOfString) / 2;
  1208.                 break;
  1209.  
  1210.             case teFlushRight:
  1211.                 localBox.left += boxWidth - widthOfString;
  1212.                 break;
  1213.  
  1214.             case teFlushLeft:
  1215.                 break;
  1216.         }
  1217.     }
  1218.  
  1219.     MoveTo(localBox.left, localBox.top + theFontInfo.ascent);
  1220.     DrawString(s);
  1221. }
  1222.  
  1223. //--------------------------------------------------------------------------------------------------
  1224. #pragma segment MAUtilitiesRes
  1225.  
  1226. pascal long PinOnRect(const Rect& theRect,
  1227.                       Point thePt)
  1228.  
  1229. {
  1230.     Point localPt = thePt;
  1231.     if (localPt.h < theRect.left)
  1232.         localPt.h = theRect.left;
  1233.     if (localPt.h > theRect.right)
  1234.         localPt.h = theRect.right;
  1235.     if (localPt.v < theRect.top)
  1236.         localPt.v = theRect.top;
  1237.     if (localPt.v > theRect.bottom)
  1238.         localPt.v = theRect.bottom;
  1239.  
  1240.     return (localPt.v << sizeof(short)) + localPt.h;
  1241. }
  1242.  
  1243. //--------------------------------------------------------------------------------------------------
  1244. #pragma segment MAUtilitiesRes
  1245.  
  1246. pascal void PinOnVRect(const VRect& theRect,
  1247.                          const VPoint& thePt,
  1248.                          VPoint& thePin)
  1249.  
  1250. {
  1251.     thePin = VPoint(MinMax(theRect.top, thePt.h, theRect.bottom), MinMax(theRect.left, thePt.h, theRect.right));
  1252. }
  1253.  
  1254. //--------------------------------------------------------------------------------------------------
  1255. #pragma segment WWSeg
  1256.  
  1257. pascal short ReadInteger(const Str255& prompt)
  1258.  
  1259. {
  1260.     short i;
  1261.  
  1262. #if qDebug
  1263.     DebugForceOutput(forceOn, forceUnchanged);
  1264. #endif
  1265.  
  1266.     fprintf(stderr, "%s", (char*)prompt);
  1267.     fscanf(stdin, "%d", &i);
  1268. #if qDebug
  1269.     DebugEndForce();
  1270. #endif
  1271.  
  1272.     return i;
  1273. }
  1274.  
  1275. //--------------------------------------------------------------------------------------------------
  1276. #pragma segment WWSeg
  1277.  
  1278. pascal Boolean ReadYesNo(const Str255& prompt)
  1279.  
  1280. {
  1281.     char userInput[10] = "";
  1282.  
  1283. #if qDebug
  1284.     DebugForceOutput(forceOn, forceUnchanged);
  1285. #endif
  1286.  
  1287.     fprintf(stderr, "%s", (char*)prompt);
  1288.     fscanf(stdin, "%s", userInput);
  1289. #if qDebug
  1290.     DebugEndForce();
  1291. #endif
  1292.  
  1293.     return ((userInput != "") && ((userInput[0] == 'y') || (userInput[0] == 'Y')));
  1294. }
  1295.  
  1296. //--------------------------------------------------------------------------------------------------
  1297. #pragma segment MAUtilitiesRes
  1298.  
  1299. pascal Boolean RectsNest(const Rect& outer,
  1300.                          const Rect& inner)
  1301.  
  1302. {
  1303.     return outer.Contains(inner);
  1304. }
  1305.  
  1306. //--------------------------------------------------------------------------------------------------
  1307. #pragma segment MAUtilitiesRes
  1308.  
  1309. pascal Boolean VRectsNest(const VRect& outer,
  1310.                           const VRect& inner)
  1311.  
  1312. {
  1313.     return outer.Contains(inner);
  1314. }
  1315.  
  1316. //--------------------------------------------------------------------------------------------------
  1317. #pragma segment MAUtilitiesRes
  1318.  
  1319. pascal long RoundUp(long aNumber,
  1320.                     short aModulus)
  1321.  
  1322. {
  1323.     return ((aNumber + aModulus - 1) / aModulus) * aModulus;
  1324. }
  1325.  
  1326. //--------------------------------------------------------------------------------------------------
  1327. #pragma segment MAUtilitiesRes
  1328.  
  1329. pascal short SetKeyScript(short newKeyScript)
  1330.  
  1331. {
  1332.     short currentKeyScript = (short)GetEnvirons(smKeyScript);
  1333.     if (currentKeyScript != newKeyScript)        // Don't unnecessarily annoy the script mgr 
  1334.         KeyScript(newKeyScript);
  1335.     return currentKeyScript;
  1336. }
  1337.  
  1338. //--------------------------------------------------------------------------------------------------
  1339. #pragma segment MAUtilitiesRes
  1340.  
  1341. pascal void SetIfBkColor(const RGBColor& aColor)
  1342.  
  1343. {
  1344.     const short SignBit = 15;
  1345.  
  1346.     if ((qNeedsColorQD || gConfiguration.hasColorQD) && IsColorPort(qd.thePort))
  1347.     {
  1348.         RGBColor tmpColor = aColor;
  1349.         
  1350.         // if color doesn't match then make trap 
  1351.         if (!EqualBlocks((Ptr) & ((CGrafPtr)qd.thePort)->rgbBkColor, (Ptr) &tmpColor, sizeof(RGBColor)))
  1352.             RGBBackColor(aColor);
  1353.     }
  1354.     else
  1355.     {
  1356.         short index = 0;                        // Prime index 
  1357.         long oldColor;
  1358.         if (aColor.red & (0x1 << SignBit))        // Set bit if red >= 0x8000 
  1359.             index = 4;
  1360.         if (aColor.green & (0x1 << SignBit))    // Set bit if green >= 0x8000 
  1361.             index = index + 2;
  1362.         if (aColor.blue & (0x1 << SignBit))        // Set bit if blue >= 0x8000 
  1363.             ++index;
  1364.         switch (index)
  1365.         {
  1366.             case 0:
  1367.                 oldColor = blackColor;
  1368.                 break;
  1369.  
  1370.             case 1:
  1371.                 oldColor = blueColor;
  1372.                 break;
  1373.  
  1374.             case 2:
  1375.                 oldColor = greenColor;
  1376.                 break;
  1377.  
  1378.             case 3:
  1379.                 oldColor = cyanColor;
  1380.                 break;
  1381.  
  1382.             case 4:
  1383.                 oldColor = redColor;
  1384.                 break;
  1385.  
  1386.             case 5:
  1387.                 oldColor = magentaColor;
  1388.                 break;
  1389.  
  1390.             case 6:
  1391.                 oldColor = yellowColor;
  1392.                 break;
  1393.  
  1394.             case 7:
  1395.                 oldColor = whiteColor;
  1396.                 break;
  1397.  
  1398.         }
  1399.         BackColor(oldColor);
  1400.     }
  1401. }
  1402.  
  1403. //--------------------------------------------------------------------------------------------------
  1404. #pragma segment MAUtilitiesRes
  1405.  
  1406. pascal void SetIfColor(const RGBColor& aColor)
  1407.  
  1408. {
  1409.     const short SignBit = 15;
  1410.  
  1411.     if ((qNeedsColorQD || gConfiguration.hasColorQD) && IsColorPort(qd.thePort))
  1412.     {
  1413.         RGBColor tmpColor = aColor;
  1414.         
  1415.         // if color doesn't match then make trap 
  1416.         if (!EqualBlocks((Ptr) & ((CGrafPtr)qd.thePort)->rgbFgColor, (Ptr) &tmpColor, sizeof(RGBColor)))
  1417.             RGBForeColor(aColor);
  1418.     }
  1419.     else
  1420.     {
  1421.         short index = 0;                        // Prime index 
  1422.         long oldColor;
  1423.  
  1424.         if (aColor.red & (0x1 << SignBit))        // Set bit if red >= 0x8000 
  1425.             index = 4;
  1426.         if (aColor.green & (0x1 << SignBit))    // Set bit if green >= 0x8000 
  1427.             index = index + 2;
  1428.         if (aColor.blue & (0x1 << SignBit))        // Set bit if blue >= 0x8000 
  1429.             ++index;
  1430.         switch (index)
  1431.         {
  1432.             case 0:
  1433.                 oldColor = blackColor;
  1434.                 break;
  1435.  
  1436.             case 1:
  1437.                 oldColor = blueColor;
  1438.                 break;
  1439.  
  1440.             case 2:
  1441.                 oldColor = greenColor;
  1442.                 break;
  1443.  
  1444.             case 3:
  1445.                 oldColor = cyanColor;
  1446.                 break;
  1447.  
  1448.             case 4:
  1449.                 oldColor = redColor;
  1450.                 break;
  1451.  
  1452.             case 5:
  1453.                 oldColor = magentaColor;
  1454.                 break;
  1455.  
  1456.             case 6:
  1457.                 oldColor = yellowColor;
  1458.                 break;
  1459.  
  1460.             case 7:
  1461.                 oldColor = whiteColor;
  1462.                 break;
  1463.         }
  1464.         ForeColor(oldColor);
  1465.     }
  1466. }
  1467.  
  1468. //--------------------------------------------------------------------------------------------------
  1469. #pragma segment MAUtilitiesRes
  1470.  
  1471. pascal void GetPortTextStyle(TextStyle& theTextStyle)
  1472.  
  1473. {
  1474.     theTextStyle.tsFont = qd.thePort->txFont;
  1475.     theTextStyle.tsFace = qd.thePort->txFace;
  1476.     theTextStyle.tsSize = qd.thePort->txSize;
  1477.     GetIfColor(theTextStyle.tsColor);
  1478. }
  1479.  
  1480. //--------------------------------------------------------------------------------------------------
  1481. #pragma segment MAUtilitiesRes
  1482.  
  1483. pascal void SetPortTextStyle(const TextStyle& theTextStyle)
  1484.  
  1485. {
  1486.     if (qd.thePort->txFont != theTextStyle.tsFont)
  1487.         TextFont(theTextStyle.tsFont);
  1488.     if (qd.thePort->txFace != theTextStyle.tsFace)
  1489.         TextFace(theTextStyle.tsFace);
  1490.     if (qd.thePort->txSize != theTextStyle.tsSize)
  1491.         TextSize(theTextStyle.tsSize);
  1492.     SetIfColor(theTextStyle.tsColor);
  1493. }
  1494.  
  1495. //--------------------------------------------------------------------------------------------------
  1496. #pragma segment MAUtilitiesRes
  1497.  
  1498. pascal void SetTextStyle(TextStyle& theTextStyle,
  1499.                          short theFont,
  1500.                          /* Style */
  1501.                          short theStyle,
  1502.                          short theSize,
  1503.                          const RGBColor& theColor)
  1504.  
  1505. {
  1506.     theTextStyle.tsFont = theFont;
  1507.     theTextStyle.tsFace = theStyle;
  1508.     theTextStyle.tsSize = theSize;
  1509.     theTextStyle.tsColor = theColor;
  1510. }
  1511.  
  1512. //--------------------------------------------------------------------------------------------------
  1513.  
  1514. pascal void StdFieldToCount(short& count,
  1515.                             short fieldType)
  1516.  
  1517. {
  1518.     switch (fieldType)
  1519.     {
  1520.         case bTextStyle:
  1521.             count = count + kTextStyleFields;
  1522.             break;
  1523.  
  1524.         case bQDProcs:
  1525.             count = count + kQDProcsFields;
  1526.             break;
  1527.  
  1528.         case bCQDProcs:
  1529.             count = count + kCQDProcsFields;
  1530.             break;
  1531.  
  1532.         case bScrapStuff:
  1533.             count = count + kScrapStuffFields;
  1534.             break;
  1535.  
  1536.         case bConfigRec:
  1537.             count = count + kConfigRecFields;
  1538.             break;
  1539.  
  1540.         case bSectionRecord:
  1541.             count = count + kSectionRecordFields;
  1542.             break;
  1543.     }
  1544. }
  1545.  
  1546. //--------------------------------------------------------------------------------------------------
  1547. #pragma segment MAUtilitiesRes
  1548.  
  1549. pascal short UprChar(short ch)
  1550.  
  1551. {
  1552.     if ((ch >= 'a') && (ch <= 'z'))
  1553.         return ch - 32;
  1554.     else
  1555.         return ch;
  1556. }
  1557.  
  1558. //--------------------------------------------------------------------------------------------------
  1559. #pragma segment MAUtilitiesRes
  1560.  
  1561. pascal void UprStr255(Str255& s)
  1562.  
  1563. {
  1564.     for (short i = 1; i <= s.Length(); i++)
  1565.         if ((s[i] >= 'a') && (s[i] <= 'z'))
  1566.             s[i] = s[i] - 32;
  1567. }
  1568.  
  1569. //--------------------------------------------------------------------------------------------------
  1570. #pragma segment MAUtilitiesRes
  1571.  
  1572. pascal void UprMAName(MAName& s)
  1573.  
  1574. {
  1575.     for (short i = 1; i <= s.Length(); i++)
  1576.         if ((s[i] >= 'a') && (s[i] <= 'z'))
  1577.             s[i] = s[i] - 32;
  1578. }
  1579.  
  1580. //--------------------------------------------------------------------------------------------------
  1581. #pragma segment MAUtilitiesRes
  1582.  
  1583. pascal void UseROMMap(Boolean resLoad)
  1584.  
  1585. {
  1586.     if (resLoad)
  1587.         (*GetROMMapInsert()) = kLMmapTrue;
  1588.     else
  1589.         (*GetROMMapInsert()) = kLMmapFalse;
  1590. }
  1591.  
  1592. //--------------------------------------------------------------------------------------------------
  1593. #pragma segment MAUtilitiesRes
  1594.  
  1595. pascal void UseSelectionColor(void)
  1596.  
  1597. {
  1598.     BitClr((Ptr)HiliteMode, 0);
  1599. }
  1600.  
  1601. //--------------------------------------------------------------------------------------------------
  1602. #pragma segment MADebug
  1603.  
  1604. pascal Boolean VerboseIsHandle(Handle h)
  1605.  
  1606. {
  1607.     const long kUnInitStorage1 = 0x72677267;    // Pascal provided uninited storage 
  1608.     const long kUnInitStorage2 = 0x67726772;    // odd byte boundary of above 
  1609.     const long kDebugHandleInit = 0xF3F3F3F3;    // Handles are inited to this in MacApp®
  1610.     const long kDebugPtrInit = 0xF5F5F5F5;        // Pointers are inited to this in MacApp®
  1611.     const long kDebugObjInit = 0xF1F1F1F1;        // Objects are inited to this in MacApp®
  1612.  
  1613.     if (((long)h & 1) != 0)
  1614.     {
  1615.         if ((long)h == kUnInitStorage1)
  1616.             fprintf(stderr, "  That handle appears to be from uninitialized storage.");
  1617.         else if ((long)h == kDebugHandleInit)
  1618.             fprintf(stderr, "  That handle appears to be from a handle initialized by debugging.");
  1619.         else if ((long)h == kDebugPtrInit)
  1620.             fprintf(stderr, "  That handle appears to be from a pointer initialized by debugging.");
  1621.         else if ((long)h == kDebugObjInit)
  1622.             fprintf(stderr, "  That handle appears to be an uninitialized instance variable.");
  1623.         else
  1624.             fprintf(stderr, "  That handle is odd.");
  1625.     }
  1626.     else if ((long)h == kUnInitStorage2)
  1627.         fprintf(stderr, "  That handle appears to be from uninitialized storage.");
  1628.     else if (h == NULL)
  1629.         fprintf(stderr, "  That handle is NULL.");
  1630.     else
  1631.     {
  1632.         Ptr masterPointer = (*h);
  1633.         if (((long)masterPointer & 1) != 0)
  1634.             fprintf(stderr, "  The master pointer is odd.");
  1635.         else if (IsFreeHandle(h))
  1636.             fprintf(stderr, "  The handle has been freed.");
  1637.         else
  1638.             return TRUE;
  1639.     }
  1640.     return FALSE;
  1641. }
  1642.  
  1643. //--------------------------------------------------------------------------------------------------
  1644. #pragma segment MAUtilitiesRes
  1645.  
  1646. pascal void WithApplicationResFileDo(pascal void(* DoWithResFile)(void* staticLink),
  1647.                                      void* staticLink)
  1648. //??? Needs a failure handler ???
  1649.  
  1650. {
  1651.     short oldResFile = CurResFile();
  1652.     UseResFile(gApplicationRefNum);
  1653.     DoWithResFile(staticLink);
  1654.     UseResFile(oldResFile);
  1655. }
  1656.  
  1657. //--------------------------------------------------------------------------------------------------
  1658. #pragma segment WWSeg
  1659.  
  1660. pascal void WriteHandleContents(Handle theHandle)
  1661.  
  1662. {
  1663.     Size Max = GetHandleSize(theHandle) - 1;
  1664.     if (Max > 0)
  1665.     {
  1666.         Boolean wasLocked = IsHandleLocked(theHandle);
  1667.         if (!wasLocked)
  1668.             HLock(theHandle);
  1669.         for (short index = 0; index <= Max; index++)
  1670.             fprintf(stderr, "%x", *((Ptr)(*theHandle + index)));
  1671.         if (!wasLocked)
  1672.             HUnlock(theHandle);
  1673.     }
  1674.     else
  1675.         fprintf(stderr, "**Empty**");
  1676. }
  1677.  
  1678. //--------------------------------------------------------------------------------------------------
  1679. #pragma segment WWSeg
  1680.  
  1681. pascal void WrLblHandleContents(const Str255& aLabel,
  1682.                                 Handle theHandle)
  1683.  
  1684. {
  1685.     fprintf(stderr, "%s = ", (char*)aLabel);
  1686.     WriteHandleContents(theHandle);
  1687. }
  1688.  
  1689. //--------------------------------------------------------------------------------------------------
  1690. #pragma segment WWSeg
  1691.  
  1692. pascal void ItsCallBack(const Str255& ,
  1693.                         const Str255& theString,
  1694.                         void* ,
  1695.                         short,
  1696.                         void*)
  1697.  
  1698. {
  1699.     fprintf(stderr, "%s", (char*)theString);
  1700. }
  1701.  
  1702.  
  1703. pascal void WriteField(Ptr fieldAddr,
  1704.                        short fieldType)
  1705.  
  1706. {
  1707.     short foo;
  1708.     FieldToString("", fieldAddr, fieldType, ItsCallBack, &foo);
  1709. }
  1710.  
  1711. //--------------------------------------------------------------------------------------------------
  1712. #pragma segment WWSeg
  1713.  
  1714. pascal void WritePt(Point pt)
  1715.  
  1716. {
  1717.     WriteField((Ptr) & pt, bPoint);
  1718. }
  1719.  
  1720. //--------------------------------------------------------------------------------------------------
  1721. #pragma segment WWSeg
  1722.  
  1723. pascal void WrLblPt(const Str255& aLabel,
  1724.                     Point pt)
  1725.  
  1726. {
  1727.     fprintf(stderr, "%s = ", (char*)aLabel);
  1728.     WritePt(pt);
  1729. }
  1730.  
  1731. //--------------------------------------------------------------------------------------------------
  1732. #pragma segment WWSeg
  1733.  
  1734. pascal void WritePtr(long val)
  1735.  
  1736. {
  1737.     WriteField((Ptr) & val, bPointer);
  1738. }
  1739.  
  1740. //--------------------------------------------------------------------------------------------------
  1741. #pragma segment WWSeg
  1742.  
  1743. pascal void WrLblPtr(const Str255& aLabel,
  1744.                      long val)
  1745.  
  1746. {
  1747.     fprintf(stderr, "%s = ", (char*)aLabel);
  1748.     WritePtr(val);
  1749. }
  1750.  
  1751. //--------------------------------------------------------------------------------------------------
  1752. #pragma segment WWSeg
  1753.  
  1754. pascal void WriteRect(const Rect& r)
  1755. {
  1756.     Rect tmpRect = r;
  1757.     
  1758.     WriteField((Ptr) &tmpRect, bRect);
  1759. }
  1760.  
  1761. //--------------------------------------------------------------------------------------------------
  1762. #pragma segment WWSeg
  1763.  
  1764. pascal void WrLblRect(const Str255& aLabel,
  1765.                       const Rect& r)
  1766.  
  1767. {
  1768.     fprintf(stderr, "%s = ", (char*)aLabel);
  1769.     WriteRect(r);
  1770. }
  1771.  
  1772. //--------------------------------------------------------------------------------------------------
  1773. #pragma segment WWSeg
  1774.  
  1775. pascal void WriteBoolean(Boolean b)
  1776.  
  1777. {
  1778.     WriteField((Ptr) & b, bBoolean);
  1779. }
  1780.  
  1781. //--------------------------------------------------------------------------------------------------
  1782. #pragma segment WWSeg
  1783.  
  1784. pascal void WrLblBoolean(const Str255& aLabel,
  1785.                          Boolean b)
  1786.  
  1787. {
  1788.     fprintf(stderr, "%s = ", (char*)aLabel);
  1789.     WriteBoolean(b);
  1790. }
  1791.  
  1792. //--------------------------------------------------------------------------------------------------
  1793. #pragma segment WWSeg
  1794.  
  1795. pascal void WriteVPt(const VPoint& pt)
  1796. {
  1797.     VPoint tmpPoint = pt;
  1798.     
  1799.     WriteField((Ptr) &tmpPoint, bVPoint);
  1800. }
  1801.  
  1802. //--------------------------------------------------------------------------------------------------
  1803. #pragma segment WWSeg
  1804.  
  1805. pascal void WrLblVPt(const Str255& aLabel,
  1806.                      const VPoint& pt)
  1807.  
  1808. {
  1809.     fprintf(stderr, "%s = ", (char*)aLabel);
  1810.     WriteVPt(pt);
  1811. }
  1812.  
  1813. //--------------------------------------------------------------------------------------------------
  1814. #pragma segment WWSeg
  1815.  
  1816. pascal void WriteVRect(const VRect& r)
  1817. {
  1818.     VRect tmpRect = r;
  1819.     
  1820.     WriteField((Ptr) &tmpRect, bVRect);
  1821. }
  1822.  
  1823. //--------------------------------------------------------------------------------------------------
  1824. #pragma segment WWSeg
  1825.  
  1826. pascal void WrLblVRect(const Str255& aLabel,
  1827.                        const VRect& r)
  1828.  
  1829. {
  1830.     fprintf(stderr, "%s = ", (char*)aLabel);
  1831.     WriteVRect(r);
  1832. }
  1833.  
  1834. //--------------------------------------------------------------------------------------------------
  1835. #pragma segment WWSeg
  1836.  
  1837. pascal void WriteSig(IDType theID)
  1838.  
  1839. {
  1840.     WriteField((Ptr) & theID, bIDType);
  1841. }
  1842.  
  1843. //--------------------------------------------------------------------------------------------------
  1844. #pragma segment WWSeg
  1845.  
  1846. pascal void WrLblSig(const Str255& theLabel,
  1847.                      IDType theID)
  1848.  
  1849. {
  1850.     fprintf(stderr, "%s = ", (char*)theLabel);
  1851.     WriteSig(theID);
  1852. }
  1853.  
  1854. //--------------------------------------------------------------------------------------------------
  1855. #pragma segment WWSeg
  1856.  
  1857. pascal void WriteHexInt(short theInt)
  1858.  
  1859. {
  1860.     WriteField((Ptr) & theInt, bHexInteger);
  1861. }
  1862.  
  1863. //--------------------------------------------------------------------------------------------------
  1864. #pragma segment WWSeg
  1865.  
  1866. pascal void WrLblHexInt(const Str255& theLabel,
  1867.                         short theInt)
  1868.  
  1869. {
  1870.     fprintf(stderr, "%s = ", (char*)theLabel);
  1871.     WriteHexInt(theInt);
  1872. }
  1873.  
  1874. //--------------------------------------------------------------------------------------------------
  1875. #pragma segment WWSeg
  1876.  
  1877. pascal void WriteHexLongint(long theLongint)
  1878.  
  1879. {
  1880.     WriteField((Ptr) & theLongint, bHexLongInt);
  1881. }
  1882.  
  1883. //--------------------------------------------------------------------------------------------------
  1884. #pragma segment WWSeg
  1885.  
  1886. pascal void WrLblHexLongint(const Str255& theLabel,
  1887.                             long theLongint)
  1888.  
  1889. {
  1890.     fprintf(stderr, "%s = ", (char*)theLabel);
  1891.     WriteHexLongint(theLongint);
  1892. }
  1893.  
  1894. //--------------------------------------------------------------------------------------------------
  1895. #pragma segment MADebug2
  1896.  
  1897. void CheckAdornment(CntlAdornment p,
  1898.                     CntlAdornment alias,
  1899.                     Str255 theString,
  1900.                     char* name)
  1901.  
  1902. {
  1903.     // "set1 <= set2" means set1 is wholly contained in set2 
  1904.     if (p <= alias)
  1905.         if (theString == Str255("["))
  1906.             theString = theString + name;
  1907.         else
  1908.             theString = theString + Str255(",") + name;
  1909. }
  1910.  
  1911.  
  1912. void CheckStyleItem(unsigned char s,
  1913.                     unsigned char alias,
  1914.                     Str255 theString,
  1915.                     char* name)
  1916.  
  1917. {
  1918.     if (s & alias)
  1919.         if (theString == Str255("["))
  1920.             theString = theString + name;
  1921.         else
  1922.             theString = theString + Str255(",") + name;
  1923. }
  1924.  
  1925.  
  1926. void DoScrapStuff(const Str255& fieldLabel,
  1927.                   ScrapStuff* theScrapStuff,
  1928.                   pascal void(* ProcessField)(const Str255& theLabel,
  1929.                                               const Str255& theString,
  1930.                                               void* theData,
  1931.                                               short theType,
  1932.                                               void* staticLink),
  1933.                   void* staticLink)
  1934.  
  1935. {
  1936.     Str255 aString = "";
  1937.     FieldToString(fieldLabel, NULL, bTitle, ProcessField, staticLink);
  1938.     FieldToString("  scrapSize", &theScrapStuff->scrapSize, bLongInt, ProcessField, staticLink);
  1939.     FieldToString("  scrapHandle", &theScrapStuff->scrapHandle, bHandle, ProcessField, staticLink);
  1940.     FieldToString("  scrapCount", &theScrapStuff->scrapCount, bInteger, ProcessField, staticLink);
  1941.     FieldToString("  scrapState", &theScrapStuff->scrapState, bInteger, ProcessField, staticLink);
  1942.     if (theScrapStuff->scrapName != NULL)
  1943.         FieldToString("  scrapName", &theScrapStuff->scrapName, bString, ProcessField, staticLink);
  1944.     else
  1945.         FieldToString("  scrapName", NULL, bPointer, ProcessField, staticLink);
  1946. }
  1947.  
  1948.  
  1949. void DoConfigRecord(const Str255& fieldLabel,
  1950.                     ConfigRecord* theConfigRecord,
  1951.                     pascal void(* ProcessField)(const Str255& theLabel,
  1952.                                                 const Str255& theString,
  1953.                                                 void* theData,
  1954.                                                 short theType,
  1955.                                                 void* staticLink),
  1956.                     void* staticLink)
  1957.  
  1958. {
  1959.     Str255 aString = "";
  1960.     FieldToString(fieldLabel, NULL, bTitle, ProcessField, staticLink);
  1961.     FieldToString("  gestaltVersion", &theConfigRecord->environsVersion, bInteger, ProcessField, staticLink);
  1962.  
  1963.     switch (theConfigRecord->machineType)
  1964.     {
  1965.         case gestaltClassic:
  1966.             aString = "gestaltClassic";
  1967.             break;
  1968.  
  1969.         case gestaltMacXL:
  1970.             aString = "gestaltMacXL";
  1971.             break;
  1972.  
  1973.         case gestaltMac512KE:
  1974.             aString = "gestaltMac512KE";
  1975.             break;
  1976.  
  1977.         case gestaltMacPlus:
  1978.             aString = "gestaltMacPlus";
  1979.             break;
  1980.  
  1981.         case gestaltMacSE:
  1982.             aString = "gestaltMacSE";
  1983.             break;
  1984.  
  1985.         case gestaltMacII:
  1986.             aString = "gestaltMacII";
  1987.             break;
  1988.  
  1989.         case gestaltMacIIx:
  1990.             aString = "gestaltMacIIx";
  1991.             break;
  1992.  
  1993.         case gestaltMacIIcx:
  1994.             aString = "gestaltMacIIcx";
  1995.             break;
  1996.  
  1997.         case gestaltMacSE030:
  1998.             aString = "gestaltMacSE030";
  1999.             break;
  2000.  
  2001.         case gestaltPortable:
  2002.             aString = "gestaltPortable";
  2003.             break;
  2004.  
  2005.         case gestaltMacIIci:
  2006.             aString = "gestaltMacIIci";
  2007.             break;
  2008.  
  2009.         default:
  2010.             aString = "gestaltMachUnknown";
  2011.             break;
  2012.     }
  2013.  
  2014.     FieldToString("  machineType", &aString, bString, ProcessField, staticLink);
  2015.  
  2016.     FieldToString("  systemVersion", &theConfigRecord->systemVersion, bHexInteger, ProcessField, staticLink);
  2017.  
  2018.     switch (theConfigRecord->processor)
  2019.     {
  2020.         case gestalt68000:
  2021.             aString = "gestalt68000";
  2022.             break;
  2023.  
  2024.         case gestalt68010:
  2025.             aString = "gestalt68010";
  2026.             break;
  2027.  
  2028.         case gestalt68020:
  2029.             aString = "gestalt68020";
  2030.             break;
  2031.  
  2032.         case gestalt68030:
  2033.             aString = "gestalt68030";
  2034.             break;
  2035.  
  2036.         case gestalt68040:
  2037.             aString = "gestalt68040";
  2038.             break;
  2039.  
  2040.         default:
  2041.             aString = "gestaltCPUUnknown";
  2042.             break;
  2043.     }
  2044.     FieldToString("  processor", &aString, bString, ProcessField, staticLink);
  2045.  
  2046.     FieldToString("  hasFPU", &theConfigRecord->hasFPU, bBoolean, ProcessField, staticLink);
  2047.     FieldToString("  hasColorQD", &theConfigRecord->hasColorQD, bBoolean, ProcessField, staticLink);
  2048.  
  2049.     switch (theConfigRecord->keyboardType)
  2050.     {
  2051.         case gestaltMacKbd:
  2052.             aString = "gestaltMacKbd";
  2053.             break;
  2054.  
  2055.         case gestaltMacAndPad:
  2056.             aString = "gestaltMacAndPad";
  2057.             break;
  2058.  
  2059.         case gestaltMacPlusKbd:
  2060.             aString = "gestaltMacPlusKbd";
  2061.             break;
  2062.  
  2063.         case gestaltExtADBKbd:
  2064.             aString = "gestaltExtADBKbd";
  2065.             break;
  2066.  
  2067.         case gestaltStdADBKbd:
  2068.             aString = "gestaltStdADBKbd";
  2069.             break;
  2070.  
  2071.         case gestaltPrtblADBKbd:
  2072.             aString = "gestaltPrtblADBKbd";
  2073.             break;
  2074.  
  2075.         case gestaltPrtblISOKbd:
  2076.             aString = "gestaltPrtblISOKbd";
  2077.             break;
  2078.  
  2079.         case gestaltStdISOADBKbd:
  2080.             aString = "gestaltStdISOADBKbd";
  2081.             break;
  2082.  
  2083.         case gestaltExtISOADBKbd:
  2084.             aString = "gestaltExtISOADBKbd";
  2085.             break;
  2086.  
  2087.         case gestaltADBKbdII:
  2088.             aString = "gestaltADBKbdII";
  2089.             break;
  2090.  
  2091.         case gestaltADBISOKbdII:
  2092.             aString = "gestaltADBISOKbdII";
  2093.             break;
  2094.  
  2095.         default:
  2096.             aString = "gestaltUnknownKbd";
  2097.             break;
  2098.     }
  2099.     FieldToString("  keyboardType", &aString, bString, ProcessField, staticLink);
  2100.  
  2101.     FieldToString("  atDrvrVersNum", &theConfigRecord->atDrvrVersNum, bInteger, ProcessField, staticLink);
  2102.     FieldToString("  sysVRefNum", &theConfigRecord->sysVRefNum, bInteger, ProcessField, staticLink);
  2103.  
  2104.     switch (theConfigRecord->teVersion)
  2105.     {
  2106.         case gestaltTE1:
  2107.             aString = "gestaltTE1";
  2108.             break;
  2109.  
  2110.         case gestaltTE2:
  2111.             aString = "gestaltTE2";
  2112.             break;
  2113.  
  2114.         case gestaltTE3:
  2115.             aString = "gestaltTE3";
  2116.             break;
  2117.  
  2118.         case gestaltTE4:
  2119.             aString = "gestaltTE4";
  2120.             break;
  2121.  
  2122.         default:
  2123.             aString = "gestaltUnknownTE";
  2124.             break;
  2125.     }
  2126.     FieldToString("  teVersion", &aString, bString, ProcessField, staticLink);
  2127.  
  2128.     FieldToString("  hasROM128K", &theConfigRecord->hasROM128K, bBoolean, ProcessField, staticLink);
  2129.     FieldToString("  hasHFS", &theConfigRecord->hasHFS, bBoolean, ProcessField, staticLink);
  2130.     FieldToString("  hasHierarchicalMenus", &theConfigRecord->hasHierarchicalMenus, bBoolean, ProcessField, staticLink);
  2131.     FieldToString("  hasScriptManager", &theConfigRecord->hasScriptManager, bBoolean, ProcessField, staticLink);
  2132.     FieldToString("  hasStyleTextEdit", &theConfigRecord->hasStyleTextEdit, bBoolean, ProcessField, staticLink);
  2133.     FieldToString("  hasSoundManager", &theConfigRecord->hasSoundManager, bBoolean, ProcessField, staticLink);
  2134.     FieldToString("  hasWaitNextEvent", &theConfigRecord->hasWaitNextEvent, bBoolean, ProcessField, staticLink);
  2135.     FieldToString("  hasSCSI", &theConfigRecord->hasSCSI, bBoolean, ProcessField, staticLink);
  2136.     FieldToString("  hasDesktopBus", &theConfigRecord->hasDesktopBus, bBoolean, ProcessField, staticLink);
  2137.     FieldToString("  hasAUX", &theConfigRecord->hasAUX, bBoolean, ProcessField, staticLink);
  2138.     FieldToString("  hasTempMem", &theConfigRecord->hasTempMem, bBoolean, ProcessField, staticLink);
  2139.     FieldToString("  has32BitQD", &theConfigRecord->has32BitQD, bBoolean, ProcessField, staticLink);
  2140.     FieldToString("  hasAppleEventMgr", &theConfigRecord->hasAppleEventMgr, bBoolean, ProcessField, staticLink);
  2141.     FieldToString("  hasEditionMgr", &theConfigRecord->hasEditionMgr, bBoolean, ProcessField, staticLink);
  2142.     FieldToString("  hasHelpMgr", &theConfigRecord->hasHelpMgr, bBoolean, ProcessField, staticLink);
  2143.     FieldToString("  hasAliasMgr", &theConfigRecord->hasAliasMgr, bBoolean, ProcessField, staticLink);
  2144.     FieldToString("  hasFolderMgr", &theConfigRecord->hasFolderMgr, bBoolean, ProcessField, staticLink);
  2145.     FieldToString("  hasProcessMgr", &theConfigRecord->hasProcessMgr, bBoolean, ProcessField, staticLink);
  2146.     FieldToString("  hasPopupCDEF", &theConfigRecord->hasPopupCDEF, bBoolean, ProcessField, staticLink);
  2147. }
  2148.  
  2149.  
  2150. void DoSectionRecord(const Str255& fieldLabel,
  2151.                      SectionRecord* theSectionRecord,
  2152.                      pascal void(* ProcessField)(const Str255& theLabel,
  2153.                                                  const Str255& theString,
  2154.                                                  void* theData,
  2155.                                                  short theType,
  2156.                                                  void* staticLink),
  2157.                      void* staticLink)
  2158. {
  2159.     Str255 aString = "";
  2160.     FieldToString(fieldLabel, NULL, bTitle, ProcessField, staticLink);
  2161.     FieldToString("  version", &theSectionRecord->version, bByte, ProcessField, staticLink);
  2162.  
  2163.     if (theSectionRecord->kind == stPublisher)
  2164.         aString = "publisher";
  2165.     else if (theSectionRecord->kind == stSubscriber)
  2166.         aString = "subscriber";
  2167.     else
  2168.         aString = "unknown";
  2169.     FieldToString("  kind", &aString, bString, ProcessField, staticLink);
  2170.  
  2171.     FieldToString("  mode", &theSectionRecord->mode, bInteger, ProcessField, staticLink);
  2172.     FieldToString("  mdDate", &theSectionRecord->mdDate, bLongInt, ProcessField, staticLink);
  2173.     FieldToString("  sectionID", &theSectionRecord->sectionID, bLongInt, ProcessField, staticLink);
  2174.     FieldToString("  refCon", &theSectionRecord->refCon, bLongInt, ProcessField, staticLink);
  2175.     FieldToString("  alias", &theSectionRecord->alias, bHandle, ProcessField, staticLink);
  2176.     FieldToString("  subPart", &theSectionRecord->subPart, bLongInt, ProcessField, staticLink);
  2177.     FieldToString("  nextSection", &theSectionRecord->nextSection, bHandle, ProcessField, staticLink);
  2178.     FieldToString("  controlBlock", &theSectionRecord->controlBlock, bHandle, ProcessField, staticLink);
  2179.     FieldToString("  refNum", &theSectionRecord->refNum, bHandle, ProcessField, staticLink);
  2180. }
  2181.  
  2182.  
  2183. pascal void StdFieldToString(const Str255& fieldLabel,
  2184.                              void* theData,
  2185.                              short fieldType,
  2186.                              pascal void(* ProcessField)(const Str255& theLabel,
  2187.                                                          const Str255& theString,
  2188.                                                          void* theData,
  2189.                                                          short theType,
  2190.                                                          void* staticLink),
  2191.                              void* staticLink)
  2192.  
  2193. {
  2194.     const short kDecPrec = 4;                    // decimal precision in extended
  2195.  
  2196.     Str255 aString = "";
  2197.     Str255 theString = "";
  2198.     // Extended support 
  2199.  
  2200.     switch (fieldType)
  2201.     {
  2202.         case bTextStyle:
  2203.             {
  2204.                 FieldToString(fieldLabel, NULL, bTitle, ProcessField, staticLink);
  2205.                 FieldToString("  Font", &((TextStyle *)theData)->tsFont, bFontName, ProcessField, staticLink);
  2206.                 FieldToString("  Face", &((TextStyle *)theData)->tsFace, bStyle, ProcessField, staticLink);
  2207.                 FieldToString("  Size", &((TextStyle *)theData)->tsSize, bInteger, ProcessField, staticLink);
  2208.                 FieldToString("  Color", &((TextStyle *)theData)->tsColor, bRGBColor, ProcessField, staticLink);
  2209.                 break;
  2210.             }
  2211.  
  2212.         case bQDProcs:
  2213.             {
  2214.                 FieldToString(fieldLabel, NULL, bTitle, ProcessField, staticLink);
  2215.                 FieldToString("  textProc", &((QDProcs *)theData)->textProc, bPointer, ProcessField, staticLink);
  2216.                 FieldToString("  textProc", &((QDProcs *)theData)->textProc, bPointer, ProcessField, staticLink);
  2217.                 FieldToString("  lineProc", &((QDProcs *)theData)->lineProc, bPointer, ProcessField, staticLink);
  2218.                 FieldToString("  rectProc", &((QDProcs *)theData)->rectProc, bPointer, ProcessField, staticLink);
  2219.                 FieldToString("  rRectProc", &((QDProcs *)theData)->rRectProc, bPointer, ProcessField, staticLink);
  2220.                 FieldToString("  ovalProc", &((QDProcs *)theData)->ovalProc, bPointer, ProcessField, staticLink);
  2221.                 FieldToString("  arcProc", &((QDProcs *)theData)->arcProc, bPointer, ProcessField, staticLink);
  2222.                 FieldToString("  polyProc", &((QDProcs *)theData)->polyProc, bPointer, ProcessField, staticLink);
  2223.                 FieldToString("  rgnProc", &((QDProcs *)theData)->rgnProc, bPointer, ProcessField, staticLink);
  2224.                 FieldToString("  bitsProc", &((QDProcs *)theData)->bitsProc, bPointer, ProcessField, staticLink);
  2225.                 FieldToString("  commentProc", &((QDProcs *)theData)->commentProc, bPointer, ProcessField, staticLink);
  2226.                 FieldToString("  txMeasProc", &((QDProcs *)theData)->txMeasProc, bPointer, ProcessField, staticLink);
  2227.                 FieldToString("  getPicProc", &((QDProcs *)theData)->getPicProc, bPointer, ProcessField, staticLink);
  2228.                 FieldToString("  putPicProc", &((QDProcs *)theData)->putPicProc, bPointer, ProcessField, staticLink);
  2229.                 break;
  2230.             }
  2231.  
  2232.         case bCQDProcs:
  2233.             {
  2234.                 FieldToString(fieldLabel, NULL, bTitle, ProcessField, staticLink);
  2235.                 FieldToString("  textProc", &((CQDProcs *)theData)->textProc, bPointer, ProcessField, staticLink);
  2236.                 FieldToString("  lineProc", &((CQDProcs *)theData)->lineProc, bPointer, ProcessField, staticLink);
  2237.                 FieldToString("  rectProc", &((CQDProcs *)theData)->rectProc, bPointer, ProcessField, staticLink);
  2238.                 FieldToString("  rRectProc", &((CQDProcs *)theData)->rRectProc, bPointer, ProcessField, staticLink);
  2239.                 FieldToString("  ovalProc", &((CQDProcs *)theData)->ovalProc, bPointer, ProcessField, staticLink);
  2240.                 FieldToString("  arcProc", &((CQDProcs *)theData)->arcProc, bPointer, ProcessField, staticLink);
  2241.                 FieldToString("  polyProc", &((CQDProcs *)theData)->polyProc, bPointer, ProcessField, staticLink);
  2242.                 FieldToString("  rgnProc", &((CQDProcs *)theData)->rgnProc, bPointer, ProcessField, staticLink);
  2243.                 FieldToString("  bitsProc", &((CQDProcs *)theData)->bitsProc, bPointer, ProcessField, staticLink);
  2244.                 FieldToString("  commentProc", &((CQDProcs *)theData)->commentProc, bPointer, ProcessField, staticLink);
  2245.                 FieldToString("  txMeasProc", &((CQDProcs *)theData)->txMeasProc, bPointer, ProcessField, staticLink);
  2246.                 FieldToString("  getPicProc", &((CQDProcs *)theData)->getPicProc, bPointer, ProcessField, staticLink);
  2247.                 FieldToString("  putPicProc", &((CQDProcs *)theData)->putPicProc, bPointer, ProcessField, staticLink);
  2248.                 FieldToString("  opcodeProc", &((CQDProcs *)theData)->opcodeProc, bPointer, ProcessField, staticLink);
  2249.                 FieldToString("  newProc1", &((CQDProcs *)theData)->newProc1, bPointer, ProcessField, staticLink);
  2250.                 FieldToString("  newProc2", &((CQDProcs *)theData)->newProc2, bPointer, ProcessField, staticLink);
  2251.                 FieldToString("  newProc3", &((CQDProcs *)theData)->newProc3, bPointer, ProcessField, staticLink);
  2252.                 FieldToString("  newProc4", &((CQDProcs *)theData)->newProc4, bPointer, ProcessField, staticLink);
  2253.                 FieldToString("  newProc5", &((CQDProcs *)theData)->newProc5, bPointer, ProcessField, staticLink);
  2254.                 FieldToString("  newProc6", &((CQDProcs *)theData)->newProc6, bPointer, ProcessField, staticLink);
  2255.                 break;
  2256.             }
  2257.  
  2258.         case bScrapStuff:
  2259.             DoScrapStuff(fieldLabel, (ScrapStuff *)theData, ProcessField, staticLink);
  2260.             break;
  2261.  
  2262.         case bConfigRec:
  2263.             DoConfigRecord(fieldLabel, (ConfigRecord *)theData, ProcessField, staticLink);
  2264.             break;
  2265.  
  2266.         case bSectionRecord:
  2267.             DoSectionRecord(fieldLabel, (SectionRecord *)theData, ProcessField, staticLink);
  2268.             break;
  2269.  
  2270.         default:                                // handle atomic datatypes 
  2271.             switch (fieldType)
  2272.             {
  2273.                 case bBoolean:
  2274.                     {
  2275.                         Str255 localString;
  2276.                         NumberToHex(*((Ptr)theData), theString, 2);
  2277.                         if (*((Boolean *)theData))
  2278.                             localString = gBoolString[1];
  2279.                         else
  2280.                             localString = gBoolString[0];
  2281.                         theString = localString + " (" + theString + ")";
  2282.                         break;
  2283.                     }
  2284.  
  2285.                 case bFontName:
  2286.                     GetFontName(*((IntegerPtr)theData), theString);
  2287.                     break;
  2288.  
  2289.                 case bInteger:
  2290.                     NumToString(*((IntegerPtr)theData), theString);
  2291.                     break;
  2292.  
  2293.                 case bLongInt:
  2294.                     NumToString(*((LongIntPtr)theData), theString);
  2295.                     break;
  2296.  
  2297.                 case bHexInteger:
  2298.                     NumberToHex(*((IntegerPtr)theData), theString, 4);
  2299.                     break;
  2300.  
  2301.                 case bHexLongInt:
  2302.                     NumberToHex(*((LongIntPtr)theData), theString, 8);
  2303.                     break;
  2304.  
  2305.                 case bHighByte:
  2306.                     NumberToHex((*((IntegerPtr)theData) & 0xFF00) >> 8, theString, 2);
  2307.                     break;
  2308.  
  2309.                 case bLowByte:
  2310.                     NumberToHex(*((IntegerPtr)theData) & 0x00FF, theString, 2);
  2311.                     break;
  2312.  
  2313.                 case bFixed:
  2314.                     {
  2315.                         NumToString(((*((LongIntPtr)theData)) & 0xFFFF0000) >> sizeof(short), aString);
  2316.                         NumToString((short)((*((LongIntPtr)theData)) & 0x0000FFFF), theString);
  2317.                         theString = aString + ":" + theString;
  2318.                         break;
  2319.                     }
  2320.  
  2321.                 case bString:
  2322.                     theString = *((Str255 *)theData);
  2323.                     break;
  2324.  
  2325.                 case bChar:
  2326.                     {
  2327.                         theString = " ";
  2328.                         theString[1] = *((Ptr)theData);
  2329.                         break;
  2330.                     }
  2331.  
  2332.                 case bGrafPtr:
  2333.                 case bWindowPtr:
  2334.                 case bPointer:
  2335.                     {
  2336.                         PointerToHex(*((LongIntPtr)theData), aString, 8);
  2337.                         if ((*((LongIntPtr)theData) & 1) != 0)
  2338.                             theString = "INVALID! (" + aString + ")";
  2339.                         else if (*((HandlePtr)theData) == NULL)
  2340.                             theString = "NULL";
  2341.                         else
  2342.                             theString = aString;
  2343.                         break;
  2344.                     }
  2345.  
  2346.                 case bRgnHandle:
  2347.                 case bControlHandle:
  2348.                 case bTEHandle:
  2349.                 case bHandle:
  2350.                     {
  2351.                         PointerToHex((long) * ((HandlePtr)theData), aString, 8);
  2352.                         if ((*((LongIntPtr)theData) & 1) != 0)
  2353.                             theString = "INVALID! (" + aString + ")";
  2354.                         else if (*((HandlePtr)theData) == NULL)
  2355.                             theString = "NULL";
  2356.                         else
  2357.                             theString = aString;
  2358.                         break;
  2359.                     }
  2360.  
  2361.                 case bPoint:
  2362.                     {
  2363.                         NumToString((*((Point *)theData)).h, aString);
  2364.                         NumToString((*((Point *)theData)).v, theString);
  2365.                         theString = "(h:" + aString + ", v:" + theString + ")";
  2366.                         break;
  2367.                     }
  2368.  
  2369.                 case bRect:
  2370.                     {
  2371.                         NumToString((*((Rect *)theData)).left, aString);
  2372.                         NumToString((*((Rect *)theData)).top, theString);
  2373.                         theString = "(l:" + aString + ", t:" + theString + ")/(r:";
  2374.                         NumToString((*((Rect *)theData)).right, aString);
  2375.                         theString = theString + aString + ", b:";
  2376.                         NumToString((*((Rect *)theData)).bottom, aString);
  2377.                         theString = theString + aString + ")";
  2378.                         break;
  2379.                     }
  2380.  
  2381.                 case bObject:
  2382.                     {
  2383.                         PointerToHex((long) * ((HandlePtr)theData), aString, 8);
  2384.                         if ((((long) * ((HandlePtr)theData)) & 1) != 0)
  2385.                             theString = "INVALID! (" + aString + ")";
  2386.                         else if (*((HandlePtr)theData) == NULL)
  2387.                             theString = "NULL";
  2388.                         else
  2389.                             theString = aString;
  2390.                         break;
  2391.                     }
  2392.  
  2393.                 case bByte:
  2394.                     NumToString(*((Ptr)theData), theString);
  2395.                     break;
  2396.  
  2397.                 case bHLState:
  2398.                     switch (*((HLState *)theData))
  2399.                     {
  2400.                         case 1:
  2401.                             theString = "hlOff";
  2402.                             break;
  2403.  
  2404.                         case 2:
  2405.                             theString = "hlDim";
  2406.                             break;
  2407.  
  2408.                         case 4:
  2409.                             theString = "hlOn";
  2410.                             break;
  2411.  
  2412.                         default:
  2413.                             NumToString(*((HLState *)theData), aString);
  2414.                             theString = "INVALID! (" + aString + ")";
  2415.                             break;
  2416.                     }
  2417.                     break;
  2418.  
  2419.                 case bCmdNumber:
  2420.                     NumToString(*((IntegerPtr)theData), theString);
  2421.                     break;
  2422.  
  2423.                 case bIDType:
  2424.                 case bResType:
  2425.                 case bOSType:
  2426.                     {
  2427.                         theString = "'    '";
  2428.                         for (short i = 1; i <= 4; i++)
  2429.                             theString[i + 1] = *((char*)(((Ptr)theData) + i - 1));
  2430.                         break;
  2431.                     }
  2432.  
  2433.                 case bPattern:
  2434.                     {
  2435.                         Str31 hexString;
  2436.                         theString = "$";
  2437.                         for (short i = 0; i <= 7; i++)
  2438.                         {
  2439.                             LIntToHex((*((Pattern *)theData))[i], hexString, 2);
  2440.                             theString = theString + hexString;
  2441.                         }
  2442.                         break;
  2443.                     }
  2444.  
  2445.                 case bRGBColor:
  2446.                     {
  2447.                         if (((*((RGBColor *)theData)).red == 0) && ((*((RGBColor *)theData)).green == 0) && ((*((RGBColor *)theData)).blue == 0))
  2448.                             theString = "Black";
  2449.                         else if (((*((RGBColor *)theData)).red == 0xFFFF) && ((*((RGBColor *)theData)).green == 0xFFFF) && ((*((RGBColor *)theData)).blue == 0xFFFF))
  2450.                             theString = "White";
  2451.                         else
  2452.                         {
  2453.                             NumberToHex((*((RGBColor *)theData)).red, theString, 4);
  2454.                             NumberToHex((*((RGBColor *)theData)).green, aString, 4);
  2455.                             theString = theString + "/" + aString;
  2456.                             NumberToHex((*((RGBColor *)theData)).blue, aString, 4);
  2457.                             theString = theString + "/" + aString;
  2458.                         }
  2459.                         break;
  2460.                     }
  2461.  
  2462.                 case bStyle:
  2463.                     {
  2464.                         theString = "[";
  2465.                         CheckStyleItem(bold, *((Style *)theData), theString, "bold");
  2466.                         CheckStyleItem(italic, *((Style *)theData), theString, "italic");
  2467.                         CheckStyleItem(underline, *((Style *)theData), theString, "underline");
  2468.                         CheckStyleItem(outline, *((Style *)theData), theString, "outline");
  2469.                         CheckStyleItem(shadow, *((Style *)theData), theString, "shadow");
  2470.                         CheckStyleItem(condense, *((Style *)theData), theString, "condense");
  2471.                         CheckStyleItem(extend, *((Style *)theData), theString, "extend");
  2472.                         theString = theString + "]";
  2473.                         break;
  2474.                     }
  2475.  
  2476.                 case bVCoordinate:
  2477.                     NumToString(*((VCoordinate *)theData), theString);
  2478.                     break;
  2479.  
  2480.                 case bVPoint:
  2481.                     {
  2482.                         NumToString((*((VPoint *)theData)).h, aString);
  2483.                         NumToString((*((VPoint *)theData)).v, theString);
  2484.                         theString = "(h:" + aString + ", v:" + theString + ")";
  2485.                         break;
  2486.                     }
  2487.  
  2488.                 case bVRect:
  2489.                     {
  2490.                         NumToString((*((VRect *)theData)).left, aString);
  2491.                         NumToString((*((VRect *)theData)).top, theString);
  2492.                         theString = "(l:" + aString + ", t:" + theString + ")/(r:";
  2493.                         NumToString((*((VRect *)theData)).right, aString);
  2494.                         theString = theString + aString + ", b:";
  2495.                         NumToString((*((VRect *)theData)).bottom, aString);
  2496.                         theString = theString + aString + ")";
  2497.                         break;
  2498.                     }
  2499.  
  2500.                 case bStringHandle:
  2501.                     {
  2502.                         if (*((HandlePtr)theData) == NULL)
  2503.                             theString = "NULL";
  2504.                         else
  2505.                             theString = ***((Str255 * **)theData);
  2506.                         break;
  2507.                     }
  2508.  
  2509.                 case bCntlAdornment:
  2510.                     {
  2511.                         theString = "[";
  2512.                         if (kFrame <= *((CntlAdornment *)theData))
  2513.                             CheckAdornment(kFrame, *((CntlAdornment *)theData), theString, "frame");
  2514.                         else
  2515.                         {
  2516.                             CheckAdornment(adnLineTop, *((CntlAdornment *)theData), theString, "top");
  2517.                             CheckAdornment(adnLineLeft, *((CntlAdornment *)theData), theString, "left");
  2518.                             CheckAdornment(adnLineBottom, *((CntlAdornment *)theData), theString, "bottom");
  2519.                             CheckAdornment(adnLineRight, *((CntlAdornment *)theData), theString, "right");
  2520.                         }
  2521.                         // CheckAdornment(adnPatFill, *((CntlAdornment*) theData), theString, "fill"); 
  2522.                         CheckAdornment(adnOval, *((CntlAdornment *)theData), theString, "oval");
  2523.                         CheckAdornment(adnRRect, *((CntlAdornment *)theData), theString, "rrect");
  2524.                         CheckAdornment(adnShadow, *((CntlAdornment *)theData), theString, "shadow");
  2525.                         theString = theString + "]";
  2526.                         break;
  2527.                     }
  2528.  
  2529.                 case bSizeDeterminer:
  2530.                     switch (*((Ptr)theData))    // ¿¿¿
  2531.                     {
  2532.                         case 0:
  2533.                             theString = "sizeSuperView";
  2534.                             break;
  2535.  
  2536.                         case 1:
  2537.                             theString = "sizeRelSuperView";
  2538.                             break;
  2539.  
  2540.                         case 2:
  2541.                             theString = "sizePage";
  2542.                             break;
  2543.  
  2544.                         case 3:
  2545.                             theString = "sizeFillPages";
  2546.                             break;
  2547.  
  2548.                         case 4:
  2549.                             theString = "sizeVariable";
  2550.                             break;
  2551.  
  2552.                         case 5:
  2553.                             theString = "sizeFixed";
  2554.                             break;
  2555.                     }
  2556.                     break;
  2557.  
  2558.                 case bReal:
  2559.                 case bSingle:
  2560.                     {
  2561.                         char destStr[80];
  2562.                         sprintf(destStr, "%f", *((float*)theData));
  2563.                         theString = destStr;
  2564.                         break;
  2565.                     }
  2566.  
  2567.                 case bDouble:
  2568.                     {
  2569.                         char destStr[80];
  2570.                         sprintf(destStr, "%f", *((double*)theData));
  2571.                         theString = destStr;
  2572.                         break;
  2573.                     }
  2574.  
  2575.                 case bExtended:
  2576.                     {
  2577.                         char destStr[80];
  2578.                         sprintf(destStr, "%e", *((extended*)theData));
  2579.                         theString = destStr;
  2580.                         break;
  2581.                     }
  2582.  
  2583.                 case bVHSelect:
  2584.                     switch (*((VHSelect *)theData))
  2585.                     {
  2586.                         case vSel:
  2587.                             theString = "v";
  2588.                             break;
  2589.  
  2590.                         case hSel:
  2591.                             theString = "h";
  2592.                             break;
  2593.  
  2594.                         default:
  2595.                             NumToString((short) * ((VHSelect *)theData), aString);
  2596.                             theString = "INVALID! (" + aString + ")";
  2597.                             break;
  2598.                     }
  2599.                     break;
  2600.             }                                    // switch for atomic types 
  2601.  
  2602.             ProcessField(fieldLabel, theString, theData, fieldType, staticLink);
  2603.     }                                            // switch for structured types 
  2604. }
  2605.  
  2606. //--------------------------------------------------------------------------------------------------
  2607. #pragma segment MAUtilitiesRes
  2608.  
  2609. typedef pascal void(* FieldToStringPtr)(const Str255& fieldLabel,
  2610.                                         void* theData,
  2611.                                         short fieldType,
  2612.                                         pascal void(* ProcessField)(const Str255& theLabel,
  2613.                                                                     const Str255& theString,
  2614.                                                                     void* theData,
  2615.                                                                     short theType,
  2616.                                                                     void* staticLink),
  2617.                                         void* staticLink);
  2618. typedef pascal void(* FieldToCountPtr)(short& count,
  2619.                                        short fieldType);
  2620.  
  2621. pascal void FieldToString(const Str255& fieldLabel,
  2622.                           void* theData,
  2623.                           short fieldType,
  2624.                           pascal void(* ProcessField)(const Str255& theLabel,
  2625.                                                       const Str255& theString,
  2626.                                                       void* theData,
  2627.                                                       short theType,
  2628.                                                       void* staticLink),
  2629.                           void* staticLink)
  2630. {
  2631.     ((FieldToStringPtr)gFieldToStrRtn)(fieldLabel, theData, fieldType, ProcessField, staticLink);
  2632. }
  2633.  
  2634. //--------------------------------------------------------------------------------------------------
  2635. #pragma segment MAUtilitiesRes
  2636. pascal void FieldToCount(short& count,
  2637.                          short fieldType)
  2638. {
  2639.     ((FieldToCountPtr)gFieldToCountRtn)(count, fieldType);
  2640. }
  2641.  
  2642. //--------------------------------------------------------------------------------------------------
  2643. #pragma segment MAUtilitiesRes
  2644. pascal long StripLong(void * address)
  2645. {
  2646.     return ((long)address & (long)gStrippedAddress);
  2647. }
  2648.  
  2649.